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 :

Récupérer Texte d'un bouton dans une Grid


Sujet :

Tkinter Python

  1. #1
    Membre actif
    Profil pro
    Inscrit en
    Février 2003
    Messages
    926
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2003
    Messages : 926
    Points : 273
    Points
    273
    Par défaut Récupérer Texte d'un bouton dans une Grid
    Bonjour,

    Je voudrais récupérer le texte d'un bouton lorsque j'y clique dessus. Voilà mon code :

    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
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    from tkinter import *
     
    master = Tk()
    L = master.winfo_screenwidth()
    H = master.winfo_screenheight()
     
    master.minsize(L,H)
    #master.geometry("320x600")
     
    class maFrame(Frame):
     
        def __init__(self, parent, *args, **kw):
            Frame.__init__(self, parent, *args, **kw)
     
            # create a canvas object
            canvas = Canvas(self, bd=0, highlightthickness=0, bg="orange")
            canvas.pack(side=LEFT, fill=BOTH, expand=TRUE)
     
            # create a frame inside the canvas which will be scrolled with it
            self.interior = interior = Frame(canvas, bg="green")
            interior_id = canvas.create_window(0, 0, window=interior, anchor=NW)
     
            def _configure_canvas(event):
                if interior.winfo_reqwidth() != canvas.winfo_width():
                    # update the inner frame's width to fill the canvas
                    canvas.itemconfigure(interior_id, width=canvas.winfo_width())
            canvas.bind('<Configure>', _configure_canvas)
     
    def OnButtonClick2():           
               #print(self.cget("text"))
               print("HOOOO!") 
     
     
    def callback() :       
        maGrid()
     
     
    if __name__ == '__main__':
     
        class maGrid(Tk):
     
            def __init__(self, *args, **kwargs):
     
               self.frame = maFrame(master)
               self.frame.pack(fill=BOTH, expand=TRUE)
     
               i = 0
               fonts = {'normal': 'arial 12','bold': 'arial 9 bold',}
               j = 0
               n = 0
     
               for mot in range(20) :                    
                        color = ['yellow', 'orange'][i % 2] 
                        myLabel = Button(self.frame.interior, text="XXX", borderwidth=10, name = "btn"+str(n), relief="sunken", fg="black", bg=color, command=self.OnButtonClick, font=fonts['normal'])#, width=taille)#anchor='ws', int(L/nbreElement)) #, 
                        myLabel.grid(row=i, column=j, padx=10, pady=10, sticky='ns') #, columnspan=29, padx=1)
                        j= j+1
                        n=n+1
                        self.frame.update()
                        pL = myLabel.winfo_rootx()+ 100# 100 étant la largeur maximale de la colonne
                        tR = master.winfo_width() + master.winfo_rootx()
                        if j>5 :
     
                            j=0
                            i = i+1
            def OnButtonClick(self):
                            print("AAA")
                            #print(self.cget("text"))
     
    b = Button(master, text="OK", command=callback)
    b.pack()
     
    mainloop()
    Si je décommente :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    print(self.cget("text"))
    ça marche pas.

    J'obtiens :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    return getattr(self.tk, attr)
    [Previous line repeated 324 more times]
    RecursionError: maximum recursion depth exceeded
    Pourriez-vous m'aider svp? Merci d'avance.
    Arsène

  2. #2
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 287
    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 287
    Points : 36 778
    Points
    36 778
    Par défaut
    Salut,

    Citation Envoyé par Arsene12 Voir le message
    Je sais que le problème vient de self qui est déjà défini autrement.
    Si vous voulez faire çà avec des "class", çà pourrait fonctionner si "self" était un Button, i.e. en fabriquant une sous-classe:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    class MyButton(Button):
             def on_click(self):
                   print (self['text'])
    Puis en l'utilisant ainsi:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    w = MyButton(text='toto')
    w['command'] = w.on_click
    w.pack()
    w.mainloop()
    Inutile de poster 70 lignes de code pour illustrer le problème (qui n'a rien à voir avec "grid") et une de ses solutions - une parmi d'autres que vous en auriez trouvé tout seul en prenant le temps d'ouvrir un tuto. sur tkinter.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  3. #3
    Membre actif
    Profil pro
    Inscrit en
    Février 2003
    Messages
    926
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2003
    Messages : 926
    Points : 273
    Points
    273
    Par défaut
    Citation Envoyé par wiztricks Voir le message
    Salut,

    Si vous voulez faire çà avec des "class", çà pourrait fonctionner si "self" était un Button, i.e. en fabriquant une sous-classe[/CODE]

    Inutile de poster 70 lignes de code pour illustrer le problème (qui n'a rien à voir avec "grid") et une de ses solutions - une parmi d'autres que vous en auriez trouvé tout seul en prenant le temps d'ouvrir un tuto. sur tkinter.

    - W

    Merci beaucoup. Je débute et chercher des exemples et consulter des tutos, c'est ce que j'arrête pas de faire. Dans mon appli, je crée des boutons en utilisant Grid. Dans la solution que vous me proposez, vous utilisez pack. Et je veux pas utiliser pack().

  4. #4
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 287
    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 287
    Points : 36 778
    Points
    36 778
    Par défaut
    Citation Envoyé par Arsene12 Voir le message
    Merci beaucoup. Je débute et chercher des exemples et consulter des tutos, c'est ce que j'arrête pas de faire. Dans mon appli, je crée des boutons en utilisant Grid. Dans la solution que vous me proposez, vous utilisez pack. Et je veux pas utiliser pack().
    Si vous voulez débutez, faites les exos d'un tuto, çà vous permettrait d'avoir/construire en plus une petite bibliothèque d'exemples à vous dans lesquels piocher inspiration et code...
    Et d'acquérir une certaine maturité/logique pour comprendre que récupérer le texte associé à un Button, il faut surtout récupérer ledit Button dans le callback, que çà n'a rien à voir avec "grid" ou "pack" et qu'il y a des tas d'autres façons de le faire.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  5. #5
    Membre actif
    Profil pro
    Inscrit en
    Février 2003
    Messages
    926
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2003
    Messages : 926
    Points : 273
    Points
    273
    Par défaut
    Citation Envoyé par wiztricks Voir le message
    Si vous voulez débutez, faites les exos d'un tuto, çà vous permettrait d'avoir/construire en plus une petite bibliothèque d'exemples à vous dans lesquels piocher inspiration et code...
    Et d'acquérir une certaine maturité/logique pour comprendre que récupérer le texte associé à un Button, il faut surtout récupérer ledit Button dans le callback, que çà n'a rien à voir avec "grid" ou "pack" et qu'il y a des tas d'autres façons de le faire.
    - W
    Au passage, quand j'avais écris mon code en javascript, je n'avais pas rencontré un tel problème.
    J'ai créé un exemple simple, le voici :

    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
    from tkinter import *
    root=Tk()
    Buts={}
     
    def OnButtonClick():
             print(r)
             print(c)
             print("AAA")
             print(Buts[r,c].cget("text"))
     
    for r in range(3):
        for c in range(4):
            Buts[(r,c)]=Button(root,text='%s/%s'%(r,c),borderwidth=10, command=OnButtonClick)
            Buts[r,c].grid(row=r,column=c)
     
     
     
    Buts[1,1]['bg']='red'
    Buts[2,2]['text']=['BUTTON2']
    Buts[2,2]['fg']=['blue']
    root.mainloop()
    Plutôt que d'utiliser self, il vaut mieux passer en paramètre les coordonnées du boutons dans la grid.

    Si on laisse command=OnButtonClick, on ne récupère pas les coordonnées i et j du bouton et

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    print(Buts[i,j-1].cget("text"))
    renvoie toujours le texte du dernier bouton.

    Voici le code pour que ça fonctionne :

    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
    from tkinter import *
    root=Tk()
    Buts={}
     
    def OnButtonClick(r,c):
             print(r)
             print(c)
             print("AAA")
             print(Buts[r,c].cget("text"))
     
    for r in range(3):
        for c in range(4):
            Buts[(r,c)]=Button(root,text='%s/%s'%(r,c),borderwidth=10, command=lambda i=r,j=c: OnButtonClick(i,j))
            Buts[r,c].grid(row=r,column=c) 
     
    Buts[1,1]['bg']='red'
    Buts[2,2]['text']=['BUTTON2']
    Buts[2,2]['fg']=['blue']
    root.mainloop()

  6. #6
    Membre actif
    Profil pro
    Inscrit en
    Février 2003
    Messages
    926
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2003
    Messages : 926
    Points : 273
    Points
    273
    Par défaut
    Voici donc la solution :

    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
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    from tkinter import *
     
    master = Tk()
    L = master.winfo_screenwidth()
    H = master.winfo_screenheight()
    Buts={}
     
    master.minsize(L,H)
    #master.geometry("320x600")
     
    class maFrame(Frame):
     
        def __init__(self, parent, *args, **kw):
            Frame.__init__(self, parent, *args, **kw)
     
            # create a canvas object
            canvas = Canvas(self, bd=0, highlightthickness=0, bg="orange")
            canvas.pack(side=LEFT, fill=BOTH, expand=TRUE)
     
            # create a frame inside the canvas which will be scrolled with it
            self.interior = interior = Frame(canvas, bg="green")
            interior_id = canvas.create_window(0, 0, window=interior, anchor=NW)
     
            def _configure_canvas(event):
                if interior.winfo_reqwidth() != canvas.winfo_width():
                    # update the inner frame's width to fill the canvas
                    canvas.itemconfigure(interior_id, width=canvas.winfo_width())
            canvas.bind('<Configure>', _configure_canvas)
     
     
    def callback() :       
        maGrid()
     
     
    if __name__ == '__main__':
     
        class maGrid(Tk):
     
     
            def __init__(self, *args, **kwargs):
     
               def OnButtonClick(r,c):
                       print(Buts[r,c].cget("text"))
     
               self.frame = maFrame(master)
               self.frame.pack(fill=BOTH, expand=TRUE)
     
               i = 0
               fonts = {'normal': 'arial 12','bold': 'arial 9 bold',}
               j = 0
               n = 0    
     
               for mot in range(20) :
                                color = ['yellow']#, 'orange'][i % 2]
                                mytext ="btn"+str(i)+str(j)
                                Buts[i,j] = Button(self.frame.interior, text=mytext, borderwidth=10, relief="sunken", fg="black", bg=color, command=lambda i=i,j=j: OnButtonClick(i,j), font=fonts['normal'])#, width=taille)#anchor='ws', int(L/nbreElement)) #, 
                                Buts[i,j].grid(row=i, column=j, padx=10, pady=10, sticky='ns') #, columnspan=29, padx=1)
     
                                j= j+1
                                n=n+1
                                self.frame.update()
                                if j>5 :
                                    j=0
                                    i = i+1
     
     
    b = Button(master, text="OK", command=callback)
    b.pack()
     
    mainloop()
    Quand je clique sur un bouton, la fonction :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
               def OnButtonClick(r,c):
                       print(Buts[r,c].cget("text"))
    me renvoie bien le texte du bouton dans la console.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
     
    # il faut bien faire command=lambda i=i,j=j: OnButtonClick(i,j), et déclarer les boutons avec leur numéro de rang et de colonne : Buts[i,j]
     
     
    Buts[i,j] = Button(self.frame.interior, text=mytext, borderwidth=10, relief="sunken", fg="black", bg=color, command=lambda i=i,j=j: OnButtonClick(i,j), font=fonts['normal'])#, width=taille)
    Buts[i,j].grid(row=i, column=j, padx=10, pady=10, sticky='ns') #, columnspan=29, padx=1)

  7. #7
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 287
    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 287
    Points : 36 778
    Points
    36 778
    Par défaut
    Citation Envoyé par Arsene12 Voir le message
    Au passage, quand j'avais écris mon code en javascript, je n'avais pas rencontré un tel problème.
    Javascript n'est pas Python/tkinter.
    Ceci dit, si vous reprenez votre petit exemple avec la solution que je vous ai indiqué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
    from tkinter import *
     
    class MyButton(Button):
        def on_click(self):
            print (self['text'])
     
    root = Tk()
     
    for r in range(3):
        for c in range(4):
            w = MyButton(text='%dx%d' % (r, c))
            w['command'] = w.on_click
            w.grid(row=r, column=c)
    root.mainloop()
    fonctionne aussi bien.

    Et vous voyez aussi que travaillez sur un petit exemple est bien plus facile que de s'encombrer de tout le code.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

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

Discussions similaires

  1. Récupérer le contenu de TextInput dans une Grid
    Par guigui-in-the-place dans le forum Qt Quick
    Réponses: 4
    Dernier message: 12/10/2011, 23h36
  2. Récupérer le numéro d'enregistrement dans une zone de texte
    Par The_Super_Steph dans le forum VBA Access
    Réponses: 18
    Dernier message: 16/05/2007, 08h50
  3. Réponses: 4
    Dernier message: 02/04/2007, 13h25
  4. Réponses: 10
    Dernier message: 10/02/2007, 18h44
  5. [CSS]problème centrage texte de bouton dans une boîte
    Par Aurelius dans le forum Mise en page CSS
    Réponses: 3
    Dernier message: 06/09/2005, 16h01

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