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 :

[Lambda] un petit test pour comprendre [Fait]


Sujet :

Tkinter Python

  1. #1
    Membre éclairé
    Avatar de airod
    Homme Profil pro
    Gérant Associé, DMP Santé et Directeur technique
    Inscrit en
    Août 2004
    Messages
    767
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Gérant Associé, DMP Santé et Directeur technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 767
    Points : 891
    Points
    891
    Par défaut [Lambda] un petit test pour comprendre
    voici un test simple de la fonction 'lambda' par rapport a une fonction utilisant 'global'

    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
    import Tkinter as tk
    x=5
     
    def ajout(x):
        x=x+2
        print 'x ajout ='+str(x)
     
    def ajoutglob():
        global x
        x=x+2
        print 'x ajout ='+str(x)
     
     
    print 'x initial=' +str(x)
     
    root=tk.Tk()
    tk.Button(root,text='Action 1',command=ajoutglob).grid()
    tk.Button(root,text='Action 2',command=lambda x=x:ajout(x)).grid()
    tk.Button(root,text='fermer',command=root.quit).grid()
    root.mainloop()
     
    root.destroy()
     
    print 'x final='+str(x)
    Je ne comprend pas du tout pourquoi le résultat est différent entre l'action du bouton 1 et du bouton 2.
    peut être ai je pas compris l'interet de lambda????
    qqu'un peut m'expliquer

  2. #2
    Membre averti
    Avatar de Alain_72
    Inscrit en
    Août 2004
    Messages
    180
    Détails du profil
    Informations forums :
    Inscription : Août 2004
    Messages : 180
    Points : 342
    Points
    342
    Par défaut
    lambda est une expression qui peut être utilisé comme une fonction.

    exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    >>>g= lambda x: x*2
    >>>g(3)
    6
    Dans le cas qui nous occupe :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    tk.Button(root,text='Action 2',command=lambda x=x:ajout(x)).grid()
    lambda est utilisé pour remplacer l'expression "command=ajout" destinée à connecter le click sur le bouton à une fonction de traitement, et ne permettant le passage d'aucun argument, par une expression lambda qui fait office de fonction, et qui peut donc passer l'argument voulu à la fonction de traitement.

    Mais cette expression lambda n'est construite qu'une seule fois lors de la création du bouton, et sera donc interprétée de la manière suivante:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    tk.Button(root,text='Action 2',command=lambda x=5:ajout(x)).grid()
    Ce qui veut dire qu'à chaque appui sur le bouton, c'est le chiffre 5 qui sera passé comme argument à ajout(), qu'elle que soit la valeur de x par la suite...

  3. #3
    Membre éclairé
    Avatar de airod
    Homme Profil pro
    Gérant Associé, DMP Santé et Directeur technique
    Inscrit en
    Août 2004
    Messages
    767
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Gérant Associé, DMP Santé et Directeur technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 767
    Points : 891
    Points
    891
    Par défaut
    d'accord jusque là c'est clair, mais dans ce cas comment faire pou que la nouvelle valeur x soit réécrite dans x.

    Dans un projet plus gros, ce souci me pose probléme lors de la création d'un rectangle sur un canvas.
    (voir post antérieur http://www.developpez.net/forums/vie....php?t=463530)

    pour dessinner le rectangle, je passe par deux fonctions
    l'une dessinne un rectangle temporaire qui varie en fonction de l'emplacement de la souris sur le canvas.
    rect_m est alors le nom dans lequel je stock la ref
    rect_m=canvas.create_rectangle(.......)
    cette fonction est lié a canvas.bind('<B1-Motion>', ma fonction)
    rect_m dois etre remplacé par le nouveau rect_m construit lors du changement de position de la souris.

    la 2eme fonction liée a canvas.bind('<B1-release>',ma fonction2)
    dois fixer mon rectangle lorsque je relache le bouton.
    il initialise la derniére valeur de rect_m et crée a la place un nouveau
    rect_m=canvas.create_rectangle(.......)

    le probléme ici c'est que mes variable passées via 'lambda' ne sont pas mis a jour et donc rect_m persiste.
    sur le canvas cela se traduit par une multiplication de rectangle qui persistent.

    comment dois je faire pour contourner le problème?
    merci d'avance.

  4. #4
    Membre averti
    Avatar de Alain_72
    Inscrit en
    Août 2004
    Messages
    180
    Détails du profil
    Informations forums :
    Inscription : Août 2004
    Messages : 180
    Points : 342
    Points
    342
    Par défaut
    Un petit exemple vaut mieux qu'un long discours.
    J'ai repris ton code sous forme d'une classe...

    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
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    #-*- coding: iso-8859-15 -*-
     
    import Tkinter as tk
    import tkMessageBox
     
    class MonApp(tk.Tk):
        mode = 0
        mPosX, mPosY = 0, 0
        cPosX, cPosY = 0, 0
        ovX, ovY = 0, 0
        rect_m = tk.NONE
        ov_m = tk.NONE
        rect_c = tk.NONE
        ov_c = tk.NONE
        dessinM = False
        dessinC = False
        blocker1 = 0
        blocker2 = 0
        coord_master = []
        coord_cadre = []
        coord_point = []
        def __init__(self):
            tk.Tk.__init__(self)
            self.canvas = tk.Canvas(self, height=400, width=400,bg="black")
            self.canvas.grid()
            tk.Button(self, text="master", command=self.modeM).grid()
            tk.Button(self, text="Cadre", command=self.modeC).grid()
            tk.Button(self, text="Quit", command=self.quit).grid()
            self.canvas.bind('<Button-1>', self.rect)
            self.canvas.bind('<ButtonRelease-1>',self.fin_rect)
            self.canvas.bind('<B1-Motion>',self.dessin_rect)
     
        def modeM(self):#bouton cadre de placement
            if self.blocker2==0:
                self.mode = 2
            else:
                tkMessageBox.showinfo('Cadrage','Vous avez déjà mis en place\n le rectangle de cadrage')
     
        def modeC(self):#bouton cadrage
            if self.blocker1==0:
                if self.blocker2 == 1:
                    self.mode = 1
            else:
                tkMessageBox.showinfo('Cadrage','Vous avez déjà mis en place\n le rectangle de cadrage')
     
        def rect(self, event):
            if self.mode == 1:
                self.cPosX, self.cPosY = event.x, event.y
                self.dessinC = True
            elif self.mode == 2:
                self.mPosX, self.mPosY = event.x, event.y
                self.dessinM = True
     
        def dessin_rect(self, event):
            if self.mode == 1:
                if self.dessinC == True:
                    lmaster,hmaster= float(self.coord_master[2] - self.coord_master[0]) ,float(self.coord_master[3] - self.coord_master[1])
                    X2,Y2=event.x,event.y
                    if X2<self.cPosX:
                        if Y2<self.cPosY:
                            Y2=self.cPosY-(((self.cPosX-X2)*hmaster)/lmaster)
                            x2,y2 = X2+ ((self.cPosX-X2)/2), (Y2+((self.cPosY-Y2)/2)) -2
                        else:
                            Y2=self.cPosY+(((self.cPosX-X2)*hmaster)/lmaster)
                            x2,y2=X2+((self.cPosX-X2)/2),(Y2-((Y2-self.cPosY)/2))-2
     
                    else:
                        if Y2<self.cPosY:
                            Y2=self.cPosY-(((self.cPosX-X2)*hmaster)/lmaster)
                            x2,y2=X2-((X2-self.cPosX)/2),(Y2+((self.cPosY-Y2)/2))-2
                        else:
                            Y2=self.cPosY+(((self.cPosX-X2)*hmaster)/lmaster)
                            x2,y2=X2-((X2-self.cPosX)/2),(Y2-((Y2-self.cPosY)/2))-2
                    if self.rect_c:
                        self.canvas.delete(self.rect_c)
                        self.canvas.delete(self.ov_c)
                    self.rect_c = self.canvas.create_rectangle(self.cPosX ,self.cPosY, X2, Y2,width = 1,outline ='green',dash= (6,4))
                    self.ov_c = self.canvas.create_oval(x2-5, y2-5 ,x2+5, y2+5,fill = 'yellow',width=1)
            elif self.mode == 2:
                if self.dessinM == True:
                    X2,Y2=event.x,event.y
                    x2,y2=X2-((X2-self.mPosX)/2),(Y2-((Y2-self.mPosY)/2))-2
                    if self.rect_m:
                        self.canvas.delete(self.rect_m)
                        self.canvas.delete(self.ov_m)
                    self.rect_m = self.canvas.create_rectangle(self.mPosX, self.mPosY, X2, Y2,width = 1,outline = 'blue', dash = (6,4))
                    self.ov_m=self.canvas.create_oval(x2-5,y2-5,x2+5,y2+5,fill='blue',width=1)
                    self.ovX = x2
                    self.ovY = y2
     
        def fin_rect(self, event):
            if self.mode == 1:
                if self.dessinC == True:
                    #self.canvas.delete(self.ov_c)
                    X,Y=event.x,event.y
                    self.coord_cadre=[self.cPosX,self.cPosY,X,Y,self.rect_c] #liste des coordonnées du rectangle
                    self.coord_point.append((self.ov_c,self.ovX,self.ovY))
                    self.blocker1=1
                    self.dessinC = False
                    self.mode = 0
            elif self.mode == 2:
                if self.dessinM == True:
                    self.canvas.delete(self.ov_m)
                    X,Y=event.x,event.y
                    self.coord_master=[self.mPosX,self.mPosY,X,Y,self.rect_m] #liste des coordonnées du rectangle
                    self.blocker2=1
                    self.dessinM = False
                    self.mode = 0
     
        def quit(self):
            self.destroy()
     
    if __name__ == '__main__':
     
    	root=MonApp()
    	root.mainloop()
    Si tu ne comprends pas tout, tu demandes...

  5. #5
    Membre éclairé
    Avatar de airod
    Homme Profil pro
    Gérant Associé, DMP Santé et Directeur technique
    Inscrit en
    Août 2004
    Messages
    767
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Gérant Associé, DMP Santé et Directeur technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 767
    Points : 891
    Points
    891
    Par défaut
    Ok, je comprend comment ca fonctionne, mes deux ensembles de fonction sont réunis en un seul ensemble.

    D'accord, petite question supp.
    revenons a coord_master

    si je veux afficher coord_master, comment faire.
    j'ai fait ca:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    coord=root.coord_master
    print coord
    mais cela me renvoie :
    []
    correspondant a la valeur initiale de coord_master et non a la nouvelle valeur (aprés que le rectangle ai été mis en place)

    merci beaucoup pour ces explications par l'exemple.

    => FAQ: http://python.developpez.com/faq/?pa...onCommandParam

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

Discussions similaires

  1. aide pour comprendre ce petit code java
    Par hassan9090 dans le forum Débuter avec Java
    Réponses: 4
    Dernier message: 22/04/2010, 16h00
  2. besoin petite explication pour comprendre ce code
    Par beta1204 dans le forum Général JavaScript
    Réponses: 3
    Dernier message: 03/06/2009, 19h47
  3. Petit test pour des pro du java
    Par vincent63 dans le forum Langage
    Réponses: 11
    Dernier message: 01/02/2008, 15h46
  4. Besoin d'aide pour comprendre un test dans un IF
    Par dante33 dans le forum Macros et VBA Excel
    Réponses: 1
    Dernier message: 06/01/2008, 21h27
  5. petit prg pour test
    Par grand's dans le forum DirectX
    Réponses: 2
    Dernier message: 07/09/2005, 14h49

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