IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Tkinter Python Discussion :

Exporter le texte d'un bouton et d'un OptionMenu [Python 2.X]


Sujet :

Tkinter Python

  1. #1
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2016
    Messages
    19
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2016
    Messages : 19
    Points : 12
    Points
    12
    Par défaut Exporter le texte d'un bouton et d'un OptionMenu
    Salut,

    Je me doute que le titre n'est pas clair, il est à l'image de mon problème.

    J'ai dans mon programme (simplifié plus bas), une liste de boutons accolés à des OptionMenu. Tous ces boutons vont appeler la même fonction (l'affichage d'un formulaire).
    Je souhaite lors de l'appelle de cette fonction l'export des 'text' des boutons, ainsi que les choix fait dans les OptionMenu correspondant.
    J'ai encapsulé les couples bouton-OptionMenu dans des frames en me disant que ça pouvait être utile pour résoudre mon problème.
    La frame1 n'est pas vraiment utile j'imagine mais je la laisse car les parties de mon programme principale sont découpée en frame.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    class Appli:
        def __init__(self):
            self.root = Tk()
            Label(self.root, text ='Choix:').grid(row =0, column =1, padx =20)
            self.frame1 = Frame(self.root, borderwidth=4, relief=GROOVE)
            self.frame1.grid(row =1, column =0)
            for i in range(4):
                fra = Frame(self.frame1, borderwidth=2, relief=RAISED)
                fra.grid()
                Button(fra, text ='Bouton'+str(i), command =self.affich).grid(row =i,column =0)
                choix = StringVar()
                OptionMenu(fra, choix, *['ab','cd','ef']).grid(row =i,column =1)
            self.root.mainloop()
     
        def affich(self):
            Label(self.root, text ='ici le texte du bouton cliquer et celui de l OptionMenu correnspondant').grid(row =1, column =1)
     
    from Tkinter import *
    f=Appli()

    Existe-il un moyen de différencier les actions déclencheur d'une fonction? De détecter si c'est le bouton 1 ou 2 qui l'appelle?

  2. #2
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 347
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 347
    Points : 36 870
    Points
    36 870
    Par défaut
    Salut,

    Pour les buttons, je vous suggère de lire explications et exemples de la FAQ.

    - W

  3. #3
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2016
    Messages
    19
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2016
    Messages : 19
    Points : 12
    Points
    12
    Par défaut
    Merci wiztricks,

    Voici donc ma solution fonctionnelle, avec l'utilisation de fermetures:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    class Appli:
        def __init__(self):
            self.root = Tk()
            Label(self.root, text ='Choix:').grid(row =0, column =1, padx =20)
            self.frame1 = Frame(self.root, borderwidth=4, relief=GROOVE)
            self.frame1.grid(row =1, column =0)
            self.nom_bouton, self.choix = [], []
            for i in range(4):
                self.nom_bouton.append('Bouton'+str(i))
                Button(self.frame1, text =self.nom_bouton[i], command =self.affich(i))\
                .grid(row =i,column =0)
                self.choix.append(StringVar())
                OptionMenu(self.frame1, self.choix[i], *['ab','cd','ef'])\
                .grid(row =i,column =1)
            self.root.mainloop()
     
        def affich(self, i):
            def manipulation():
                Label(self.root, text ='Nom du bouton cliquer : '+self.nom_bouton[i]\
                +'\nOption correpondante : ' +self.choix[i].get()).grid(row =1, column =1)
            return manipulation
     
    from Tkinter import *
    f=Appli()
    Bien cordialement.

  4. #4
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2016
    Messages
    19
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2016
    Messages : 19
    Points : 12
    Points
    12
    Par défaut
    Bonjour,

    Je ré-ouvre ce post car je souhaite maintenant appeler la fonction disposant d'un fermeture simplement en ligne.
    J'ai créé un autre bouton lié à la fonction self.declenche, qui devrait, selon moi, simplement appeler la fonction self.affich comme le font les autres boutons.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    class Appli:
        def __init__(self):
            self.root = Tk()
            Label(self.root, text ='Choix:').grid(row =0, column =1, padx =20)
            self.frame1 = Frame(self.root, borderwidth=4, relief=GROOVE)
            self.frame1.grid(row =1, column =0)
            self.nom_bouton, self.choix = [], []
            for i in range(4):
                self.nom_bouton.append('Bouton'+str(i))
                Button(self.frame1, text =self.nom_bouton[i], command =self.affich(i))\
                .grid(row =i,column =0)
                self.choix.append(StringVar())
                OptionMenu(self.frame1, self.choix[i], *['ab','cd','ef'])\
                .grid(row =i,column =1)
            Button(self.root, text ='Declenche', command =self.declenche)\
            .grid(row =2, column =0)
            self.root.mainloop()
     
        def affich(self, i):
            def manipulation():
                Label(self.root, text ='Nom du bouton cliquer : '+self.nom_bouton[i]\
                +'\nOption correpondante : ' +self.choix[i].get()).grid(row =1, column =1)
            return manipulation
     
        def declenche(self):
            for i in range(4):
                self.affich(i)
     
    from Tkinter import *
    f=Appli()
    Mais voilà, ça ne fonctionne pas.
    Comment déclencher cette fonction avec fermeture simplement avec une ligne de code? Est-ce possible ou faut-il obligatoirement la lier à un bouton?

    Edit: Je me demande si il est possible pour moi de changer le titre de la discussion, pour un plus clair.

  5. #5
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 347
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 347
    Points : 36 870
    Points
    36 870
    Par défaut
    Citation Envoyé par Shozma Voir le message
    J'ai créé un autre bouton lié à la fonction self.declenche, qui devrait, selon moi, simplement appeler la fonction self.affich comme le font les autres boutons.
    command=self.declenche() exécute la fonction et son retour serait à appeler lorsqu'on clique sur le bouton. Malheureusement, cette fonction ne retourne pas (comme affich) une fonction... De plus "comma" au lieu de "command" devrait raler.
    Essayez de relire votre code et de comprendre s'il a des chances de faire ce que vous attendez.

    - W

  6. #6
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2016
    Messages
    19
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2016
    Messages : 19
    Points : 12
    Points
    12
    Par défaut
    Deux erreurs de relecture effectivement. J'ai édité mon message précédent.

    Mais ça ne fonctionne toujours pas, j'essaye de comprendre la raison... en vain.
    Je ne comprend pas pourquoi la fonction affich(self, i) appelé simplement avec:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    for i in range(4):
        self.affich(i)
    ne s’exécute pas comme lorsqu'elle est appelée par un bouton.

  7. #7
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 347
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 347
    Points : 36 870
    Points
    36 870
    Par défaut
    Citation Envoyé par Shozma Voir le message
    Mais ça ne fonctionne toujours pas, j'essaye de comprendre la raison... en vain.
    Je ne comprend pas pourquoi la fonction affich(self, i) appelé simplement avec:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    for i in range(4):
        self.affich(i)
    ne s’exécute pas comme lorsqu'elle est appelée par un bouton.
    Parce que vous ne comprenez toujours pas le code que vous avez écrit.
    Réfléchissez encore: self.affich(i) retourne une fonction.
    C'est cette fonction là qui est appelée lors du clic... mais elle n'est pas appelée dans "declenche"... donc elle ne s'exécute pas.

    - W

  8. #8
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2016
    Messages
    19
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2016
    Messages : 19
    Points : 12
    Points
    12
    Par défaut
    J'essaye de comprendre, j'expérimente.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    def fonction1():
        return fonction2()
    def fonction2():
        return fonction3()
    def fonction3():
        return 'voila'
    >>> fonction1() me renvoi 'voila'
    Donc il faudrait que "declenche" appelle "affich" qui appellerait "manipulation".
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
        def declenche(self):
            return self.affich(0)
    par exemple si on veut l'action du premier bouton (moi, avec "declenche", je voudrai appuyer sur tous les boutons en même temps).
    Vous savez sûrement déjà que ça ne fonctionne pas...

    Alors peut-être qu'il faut appeler "manipulation" directement !
    Mais vu qu'elle n'est déclaré que dans "affich", je la sors, tel quel:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
        def affich(self, i):
            return self.manipulation(i)
     
        def manipulation(self, i):
            Label(self.root, text ='Nom du bouton cliquer : '+self.nom_bouton[i])\
            .grid(row =1, column =1)
     
        def declenche(self):
            return self.affich(0)
    Le bouton Declenche fonctionne, mais c'est les autres qui ne fonctionnent plus.

    Vous avez raison je ne comprend pas mon code... help

  9. #9
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 347
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 347
    Points : 36 870
    Points
    36 870
    Par défaut
    Salut,

    Il faudrait savoir si vous voulez une fermeture ou pas et réfléchir à la différence entre retourner une fonction qui sera appelée plus tard avec appeler la fonction directement. Essayez voir:
    Une fonction bête:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    >>> def g():
    ...    return "je suis G"
    ...
    >>>
    Quand on l'appelle:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    >>> g()
    'je suis G'
    >>>
    Une fonction qui retourne une fonction:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    >>> def f():
    ...    return g
    ...
    >>>
    Si on l'appelle çà retourne "g" sans l'appeler:
    Maintenant, si on appelle la fonction qui a été retournée:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    >>> _()
    'je suis G'
    >>>
    Et dans tout ce bazar, la différence n'est que placement ou omission de "()" qui fera qu'on appelle ou pas et qui promeut la simple fonction en fermeture/closure.

    Essayez de faire travailler vos neurones encore un peu...

    - W

  10. #10
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2016
    Messages
    19
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2016
    Messages : 19
    Points : 12
    Points
    12
    Par défaut
    Je veux la fermeture effectivement donc la fonction manipulation doit être encapsulée.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    class Appli:
        def __init__(self):
            self.root = Tk()
            Label(self.root, text ='Choix:').grid(row =0, column =1, padx =20)
            self.frame1 = Frame(self.root, borderwidth=4, relief=GROOVE)
            self.frame1.grid(row =1, column =0)
            self.nom_bouton = []
            for i in range(4):
                self.nom_bouton.append('Bouton'+str(i))
                Button(self.frame1, text =self.nom_bouton[i], command =self.affich(i))\
                .grid(row =i,column =0)
            self.root.mainloop()
     
        def affich(self, i):
            def manipulation():
                Label(self.root, text ='Nom du bouton cliquer : '+self.nom_bouton[i]\
                +'\nOption correpondante : ' +self.choix[i].get()).grid(row =1, column =1)
            return manipulation
    Et cela veut donc dire qu'il n'y a aucun moyen d'appuyer sur les quatre boutons "en même temps", comme je souhaite le faire avec la fonction declenche?

  11. #11
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 347
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 347
    Points : 36 870
    Points
    36 870
    Par défaut
    Citation Envoyé par Shozma Voir le message
    Et cela veut donc dire qu'il n'y a aucun moyen d'appuyer sur les quatre boutons "en même temps", comme je souhaite le faire avec la fonction declenche?
    Il faut juste ne pas oublier de mettre les parenthèses:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
         for i in range(4):
              self.affich(i)()
    - W

  12. #12
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2016
    Messages
    19
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2016
    Messages : 19
    Points : 12
    Points
    12
    Par défaut
    Merci

  13. #13
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 347
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 347
    Points : 36 870
    Points
    36 870
    Par défaut
    Salut,

    Juste pour le fun: utilisation de lambda et de Button.invoke
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    import Tkinter as tk
     
    def manipulation(nom, choix, label):
        label['text'] = 'bouton: %s, option: %s' % (nom, choix)
     
    def declenche(btns):
        for b in btns:
            b.invoke()
     
     
    root = tk.Tk()
     
    tk.Label(root, text ='Choix:').grid(row =0, column =2, padx =20)
     
    buttons = []
    for i in range(1, 5):
        nom = 'B-'+str(i)
        choix = tk.StringVar(root)
        label = tk.Label(root, width=20)
     
        btn = tk.Button(root, text=nom,
               command=lambda nom=nom, choix=choix, label=label: manipulation(nom, choix.get(), label)
               )
        btn.grid(row =i,column =0)
        buttons.append(btn)
     
        tk.OptionMenu(root,
                   choix, 'ab','cd','ef').grid(row =i,column =1)
     
        label.grid(row=i, column=2)
     
    w = tk.Button(root, text ='Declenche', command =lambda: declenche(buttons))
    w.grid(row=5, column=1, columnspan=3)
     
    tk.mainloop()
    Vous noterez que j'ai viré votre classe.
    Si on veut s'amuser avec les classes, on part du principe qu'une classe va permet d'abord de fabriquer plusieurs objets aux propriétés semblables. Ici, l'objet qui se répète est la row composée des 3 widgets Button, OptionMenu et Label. Ce qui va permettre de fabriquer une commande qui soit méthode associée à chaque objet et donc ne plus avoir à passer par la fermeture.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    import Tkinter as tk
     
    class MyRow(tk.Button):
        def __init__(self, master, row):
            self.nom = 'B-'+str(i)
            tk.Button.__init__(self, root, text=self.nom,
               command=self.affiche)
     
            self.grid(row=row, column=0)
            self.choix = tk.StringVar(root)
     
            tk.OptionMenu(root, self.choix, 'ab','cd','ef'
                   ).grid(row=row, column=1)
     
            self.label = tk.Label(root, width=20)
            self.label.grid(row=row, column=2)
     
        def affiche(self):
            self.label['text'] = 'bouton: %s, option: %s' % (self.nom, self.choix.get())
     
     
    root = tk.Tk()
     
    tk.Label(root, text ='Choix:').grid(row =0, column =2, padx =20)
    label =  tk.Label(root, text ='')
    buttons = []
    for i in range(1, 5):
        btn = MyRow(root, i)
        buttons.append(btn)
     
    def declenche():
        for b in buttons:
            b.invoke()
     
     
    w = tk.Button(root, text ='Declenche', command = declenche)
    w.grid(row=5, column=1, columnspan=3)
     
    tk.mainloop()
    - W

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [SWT]image ET text sur un bouton SWT
    Par piwai dans le forum SWT/JFace
    Réponses: 14
    Dernier message: 04/10/2006, 15h41
  2. Changer dynamiquement le texte d'un bouton
    Par memess dans le forum Flash
    Réponses: 2
    Dernier message: 04/11/2005, 09h38
  3. Orientation texte dans un bouton
    Par miky_jo dans le forum Composants
    Réponses: 1
    Dernier message: 03/11/2005, 10h34
  4. [JButton] Afficher texte en survolant bouton.
    Par Galima dans le forum Composants
    Réponses: 2
    Dernier message: 04/06/2004, 22h21
  5. Réponses: 9
    Dernier message: 26/04/2004, 21h51

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo