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

Python Discussion :

Tkinter et les Buttons myst�re !


Sujet :

Python

  1. #1
    Membre �clair�
    Avatar de Captain'Flam
    Homme Profil pro
    Ing�nieur d�veloppement logiciels
    Inscrit en
    F�vrier 2011
    Messages
    273
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activit� : Ing�nieur d�veloppement logiciels

    Informations forums :
    Inscription : F�vrier 2011
    Messages : 273
    Billets dans le blog
    1
    Par d�faut Tkinter et les Buttons myst�re !
    Bonjour,

    j'�tais en train de coder un petit dialog tout ce qu'il y a de plus simple en Tkinter quand je suis tomb� sur un comportement des plus myst�rieux !

    Voici la b�te (tout est dans les commentaires) :
    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
    #coding:cp1252
     
    # affiche une boîte de dialogue simple : 
    #  - une listbox contenant un texte de quelques lignes 
    #  - des boutons qui lancent des actions sur ce texte
    def main_menu ( lines,buttons ):
        import Tkinter
        root = Tkinter.Tk()
        # la listbox
        listbox = Tkinter.Listbox( root )
        for f in lines : listbox.insert( Tkinter.END,f )
        listbox.pack()
        # les boutons = paires ( libélé , fonction )
        for name,func in buttons :
            print name,func # quelques traces pour vérifier
            butt = Tkinter.Button( root,text = name,command = lambda : func( lines ))
            butt.pack()
        # et c'est parti !
        root.mainloop()
     
    def message ( *t ) : # ch'tite fonction qui ne fait pas grand chose... 
        print t
     
    # 10 lignes de texte sans intèret
    lines = ['-- %d '%i+'-'*i for i in xrange( 10 )]
     
    # liste de paires ( libellé du bouton , fonction associée )]
    buttons  = [('button %d'%i , lambda l : message( 'Button %d'%i,l[i:i+2] )) for i in xrange( 5 )]
     
    # appel du dialog
    main_menu( lines,buttons ) #---> tous les boutons lancent la même fonction (la dernière)
     
    # peut-être qu'il n'aime pas un tableau de lambdas construites à la volée ?
    # Ok, je définis mes fonctions une par une :  
    def s1 ( l ) : message( 's1',l[0] )
    def s2 ( l ) : message( 's2',l[0:2] )
    def s3 ( l ) : message( 's3',l[1:5] )
    buttons2 = [('s1',s1),('s2',s2),('s3',s3)]
    main_menu( lines,buttons2 ) #---> idem !!!
    Je lance mon machin et clique sur chaque bouton : voici les traces que j'obtiens sur la console :
    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
    button 0 <function <lambda> at 0x02AC4470>
    button 1 <function <lambda> at 0x02AC43F0>
    button 2 <function <lambda> at 0x02AC4630>
    button 3 <function <lambda> at 0x02AC4670>
    button 4 <function <lambda> at 0x02AC46B0>
    ('Button 4', ['-- 4 ----', '-- 5 -----'])
    ('Button 4', ['-- 4 ----', '-- 5 -----'])
    ('Button 4', ['-- 4 ----', '-- 5 -----'])
    ('Button 4', ['-- 4 ----', '-- 5 -----'])
    ('Button 4', ['-- 4 ----', '-- 5 -----'])
    s1 <function s1 at 0x02AC4AF0>
    s2 <function s2 at 0x02AC46F0>
    s3 <function s3 at 0x02AC4530>
    ('s3', ['-- 1 -', '-- 2 --', '-- 3 ---', '-- 4 ----'])
    ('s3', ['-- 1 -', '-- 2 --', '-- 3 ---', '-- 4 ----'])
    ('s3', ['-- 1 -', '-- 2 --', '-- 3 ---', '-- 4 ----'])
    Comme on le voit, les fonctions pass�es � Button sont bien diff�rentes mais seule la derni�re semble appel�e...

    Quelqu'un y comprend-il quelque chose ?

    Merci d'avance !

  2. #2
    Expert �minent
    Homme Profil pro
    Architecte technique retrait�
    Inscrit en
    Juin 2008
    Messages
    21 772
    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 772
    Par d�faut
    Salut,
    La question est de savoir a quoi seront instanci�es les "variables" avec lesquelles sont d�clar�es/construites les lambda lorsqu'elles seront appel�es.
    Exemple, en �crivant:
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    buttons  = [('button %d'%i , lambda l: message( 'Button %d'%i,l[i:i+2] )) for i in xrange( 5 )]
    que vaudra "i" a l'appel du lambda: 5.
    Ecrivons cela autrement:
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    def mylambda(l):
          message('Button %d'%i,l[i:i+2] ))
    Ce foutu "i" est a priori une sorte de variable "globale" (dans un scope externe).
    Pour s'en sortir, il faut coller le "i" dans les param�tres de la fonction:
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    buttons  = [('button %d'%i , lambda l, i=i: message( 'Button %d'%i,l[i:i+2] )) for i in xrange( 5 )]
    De m�me, dans la boucle for name, func...
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    Tkinter.Button( root,text = name,command = lambda func=func: func( lines ))
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  3. #3
    Membre �clair�
    Avatar de Captain'Flam
    Homme Profil pro
    Ing�nieur d�veloppement logiciels
    Inscrit en
    F�vrier 2011
    Messages
    273
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activit� : Ing�nieur d�veloppement logiciels

    Informations forums :
    Inscription : F�vrier 2011
    Messages : 273
    Billets dans le blog
    1
    Par d�faut
    En effet, �a fonctionne !

    J'ai trouv� un exemple beaucoup plus condens� :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    >>> [lambda : i for i in ( 3,4,5 )]
    [<function <lambda> at 0x027F3EB0>, <function <lambda> at 0x027F3E30>, <function <lambda> at 0x027F3E70>]
    On voit bien qu'on a des fonctions diff�rentes.

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    >>> [lambda : i for i in ( 3,4,5 )][0]()
    5
    Mais le "i" de chacun instance semble valoir 5.

    Si on ajoute un param�tre avec une valeur par d�faut (ce qui permet de mimer une fonction sans param�tre), �a marche :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    >>> [lambda j=i : j for i in ( 3,4,5 )][0]()
    3
    je suis bien content d'avoir compris ce truc, mais il faudrait dire � Guido (ou ses successeurs) que ce n'est pas joli joli (� moins qu'il y ait une excellente raison qui m'�chappe encore)...

    Un grand merci !

  4. #4
    Expert �minent
    Homme Profil pro
    Architecte technique retrait�
    Inscrit en
    Juin 2008
    Messages
    21 772
    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 772
    Par d�faut
    Citation Envoy� par Captain'Flam Voir le message
    je suis bien content d'avoir compris ce truc, mais il faudrait dire � Guido (ou ses successeurs) que ce n'est pas joli joli (� moins qu'il y ait une excellente raison qui m'�chappe encore)..
    Hmm... C'est pas facile a raconter. La fa�on la plus "rapide" est de se souvenir qu'en Python, il y a un monde d'objets et un code interpr�t� qui y acc�de via ces chemins qu'on appelle "variables".
    En �crivant:
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    L = [ lambda : i for i in ( 3,4,5 ) ]
    On pense "valeur de i" alors qu'en fait ce sera l'objet r�f�renc� par la variable "i" lorsque la fonction sera �valu�e.
    Exemple:
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    >>> L = [ lambda : i for i in range(3) ]
    >>> i
    2
    >>> L[0]()
    2
    >>> i = 7
    >>> L[0]()
    7
    En �crivant:
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    L = [ lambda i=i: i for i in range(3) ]
    On cr�e, par effet de bord, un chemin "i" dans l'espace locals() de la fonction par l'assignation (une r�f�rence) a l'objet accessible par le chemin "i" globals() lors de sa construction.
    La d�claration de param�tres avec des valeurs par d�faut:
    ne fait rien d'autre.

    Une partie de cette m�canique est li�e a la nature "interpr�t�e" du langage (et se retrouve en assembleur). Ce qui est sp�cifique Python est la s�paration entre chemins et objets: que des r�f�rences, pas de "valeur" .
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  5. #5
    Membre �clair�
    Avatar de Captain'Flam
    Homme Profil pro
    Ing�nieur d�veloppement logiciels
    Inscrit en
    F�vrier 2011
    Messages
    273
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activit� : Ing�nieur d�veloppement logiciels

    Informations forums :
    Inscription : F�vrier 2011
    Messages : 273
    Billets dans le blog
    1
    Par d�faut
    Arf... je comprends...

    Cette explication r�v�le un autre truc assez pervers :
    Les variables utilis�es dans les listes en compr�hension ne sont pas muettes.

    Quand on �crit
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    L = [ i for i in ( 3,4,5 ) ]
    en plus de L (qui vaudra [3,4,5], on cr�� aussi la variable globale i qui aura la valeur 5.

    Et si i existait avant, elle sera �cras�e...

    On aurait pu imaginer que ce i soit une variable locale de compr�hension.

    Mais en faisant d'autres tests autour de cette question, je suis tomb� sur un truc encore plus bizarre :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    >>> LL = lambda : [ lambda : u for u in ( 3,4,5 ) ]
    >>> L = LL()
    >>> L[0]()
    5  # retourne la valeur courante de la variable 'u'
    >>> u
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    NameError: name 'u' is not defined    # toutefois 'u' ne semble pas définie !
    Dans cet exemple, que retourne vraiment L[0]() ?
    u existe-elle quelque part, dans un endroit inaccessible ?

  6. #6
    Expert �minent
    Homme Profil pro
    Architecte technique retrait�
    Inscrit en
    Juin 2008
    Messages
    21 772
    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 772
    Par d�faut
    Citation Envoy� par Captain'Flam Voir le message
    Quand on �crit
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    L = [ i for i in ( 3,4,5 ) ]
    en plus de L (qui vaudra [3,4,5], on cr�� aussi la variable globale i qui aura la valeur 5.

    Et si i existait avant, elle sera �cras�e...

    On aurait pu imaginer que ce i soit une variable locale de compr�hension.
    Heu? Essayez pour voir, vous serez encore plus perplexe.
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  7. #7
    Membre �clair�
    Avatar de Captain'Flam
    Homme Profil pro
    Ing�nieur d�veloppement logiciels
    Inscrit en
    F�vrier 2011
    Messages
    273
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activit� : Ing�nieur d�veloppement logiciels

    Informations forums :
    Inscription : F�vrier 2011
    Messages : 273
    Billets dans le blog
    1
    Par d�faut
    Essayez pour voir, vous serez encore plus perplexe.
    Je ne comprends pas... que fait-il que j'essaie ?

  8. #8
    Expert �minent
    Homme Profil pro
    Architecte technique retrait�
    Inscrit en
    Juin 2008
    Messages
    21 772
    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 772
    Par d�faut
    Citation Envoy� par Captain'Flam Voir le message
    Je ne comprends pas... que fait-il que j'essaie ?
    Essayez de faire marcher votre code, vous verrez qu'il n'y a pas de "i" dans le globals().
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  9. #9
    Membre �clair�
    Avatar de Captain'Flam
    Homme Profil pro
    Ing�nieur d�veloppement logiciels
    Inscrit en
    F�vrier 2011
    Messages
    273
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activit� : Ing�nieur d�veloppement logiciels

    Informations forums :
    Inscription : F�vrier 2011
    Messages : 273
    Billets dans le blog
    1
    Par d�faut
    Heu... b� si ! i est bien dans globals() :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    >>> L = [ i for i in ( 3,4,5 ) ]
    >>> L
    [3, 4, 5]
    >>> i
    5
    >>> globals()
    {'__builtins__': <module '__builtin__' (built-in)>, 'L': [3, 4, 5], '__package__': None, 'i': 5, '__name__': '__main__', '__doc__': None}

  10. #10
    Expert �minent
    Homme Profil pro
    Architecte technique retrait�
    Inscrit en
    Juin 2008
    Messages
    21 772
    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 772
    Par d�faut
    Ah oui, enfin, c'est dans globals() mais en 2.7.
    Sous 3.3:
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    Python 3.3.2 (v3.3.2:d047928ae3f6, May 16 2013, 00:03:43) [MSC v.1600 32 bit (In
    tel)] on win32
    Type "help", "copyright", "credits" or "license" for more information.
    >>> L = [ i for i in (3,4,5) ]
    >>> i
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    NameError: name 'i' is not defined
    >>>
    - 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. python, tkinter et les sockets (et les threads)
    Par bomberwaterman dans le forum R�seau/Web
    R�ponses: 6
    Dernier message: 02/01/2009, 19h53
  2. Look & Feel : pb pour modifier les Button
    Par BenHoit dans le forum AWT/Swing
    R�ponses: 5
    Dernier message: 12/06/2008, 14h40
  3. R�ponses: 2
    Dernier message: 19/12/2007, 17h52
  4. Question sur Les Button
    Par saih_tam dans le forum AWT/Swing
    R�ponses: 2
    Dernier message: 04/04/2007, 18h26
  5. Tkinter et les accents
    Par Chris33 dans le forum Tkinter
    R�ponses: 3
    Dernier message: 09/10/2006, 21h57

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