Forum Programmation.python instanciation objet tk.button et appels de fonctions

Posté par  . Licence CC By‑SA.
Étiquettes : aucune
0
20
juin
2020

Bonjour,
je veux créer des boutons dans une boucle for pour avoir un code plus propre mais j'ai un soucis dans l'appels des fonctions lorsqu'on clique sur le bouton.
mon code est ainsi :

categories=[item1,item2,item3,item4,item5]
for cat in categories:
tk.Button(self,text=str(cat),command=lambda:self.Categorie1(cat),controller.show_frame(CatTwo)]).pack()
Les boutons sont instanciés avec le bon texte. Par contre, lorsque je clique sur un bouton, la fonction Categorie1 est appelé avec la meme valeur de cat pour tous les boutons. Est ce que vous avez des suggestions pour éviter cela en gardant la boucle for?

  • # Idée

    Posté par  . Évalué à 3.

    Salut,

    Le paramètre ne serait pas toujours item5 ? :)

    Si c'est ça, j'ai une petite idée de ce qui se trame derrière.

    Matricule 23415

  • # Piège python classique

    Posté par  (site web personnel) . Évalué à 3.

    Oui c'est un truc piégeux de python que la façon dont le contexte est capturé ; on pense que chaque for va créer un nouveaux contexte, mais non, et du coup tes lambda utilisent la dernière valeur pour cat.

    Il y a plusieurs façon de s'en sortir. Tu peux instancier ton instance de Button dans une fonction (chaque appel de fonction a bien son propre contexte—que va capturer ta lambda). Sinon il y a une astuce:

    Ça c'est ce que tu fais :

    functions = []
    for i in range(3):
         functions.append(lambda: print(i))
    
    for func in functions: 
       func()

    et qui va afficher :
    2
    2
    2

    Mais si tu écris "functions.append(lambda x=i: print(x))" (note le paramètre nommé "x"—il pourrait s'appeler "i" aussi) alors ça écrira bien:
    0
    1
    2

    • [^] # Re: Piège python classique

      Posté par  . Évalué à 2.

      Salut,

      Oui c'est un truc piégeux de python

      Si y'avait qu'en python… :)

      C'est un piège assez commun ;)

      Moi je voulais laisser l'OP réfléchir encore un peu, mais t'as donné le truc :p

      Matricule 23415

  • # au top

    Posté par  . Évalué à 1.

    merci ca roule

    • [^] # Re: au top

      Posté par  . Évalué à 2.

      Salut,

      Ne t'inquiète pas.

      C'est le genre d'erreur, si tu ne l'a pas fait dans ta vie, c'est que tu vas vite la faire :)

      Je voulais te laisser réfléchir un peu, mais j'ai été grillé :)

      Matricule 23415

    • [^] # Re: au top

      Posté par  . Évalué à 2.

      en plus en python, il faut garder les indentations

      là visiblement tu as collé ton code sans utiliser la bonne syntaxe du forum, le code perd ces indentations, et ca ne fonctionne plus

      pour du code python il faut taper

      ```python
      def mafonction(x):
      lecode dans ma fonction
      try:
      exemple de code
      ```

      ce qui donnera le rendu suivant :

      def mafonction(x):
        lecode dans ma fonction
        try:
          exemple de code

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.