Partage
  • Partager sur Facebook
  • Partager sur Twitter

Tkinter - Boutons dans une boucle

Définir des boutons qui ont des actions différantes avec une boucle

Sujet résolu
    23 septembre 2018 à 22:43:58

    Bonjour à tous !

    J'aimerais définir des boutons à travers une boucle (j'ai 64 boutons à placer en 8x8 pour un plateau de jeu) grâce au module Tkinter.

    J'ai déjà pu définir les boutons et leur afficher l'image correspondante (qui varie en fonction du bouton), cependant, la commande exécutée lors du clic sur un bouton doit dépendre du bouton sur lequel on a cliqué. Malheureusement, l'action effectuée est TOUJOURS celle du dernier bouton (en effet, la variable self.i évolue au fil des créations de bouton).

    Voici la partie intéressante de mon code :

    	def initialisationPlateau(self, L, C):
    		try:
    			self.image_piece_file = "images/{piece}.gif".format(piece = self.pieces["{colonne}{ligne}".format(colonne = self.lettres[C],ligne = L+1)])
    		except KeyError:
    			self.image_piece_file = "images/Vide.gif"
    		self.image_piece[self.i] = tk.PhotoImage(file = self.image_piece_file)
    		if (L % 2 == 0 and C % 2 == 0) or (L % 2 == 1 and C % 2 == 1):
    			tk.Button(self, image = self.image_piece[self.i], command = lambda: self.detectCaseClic(self.i), bg = "white", borderwidth = 1).grid(row = L+2, column = C+1, sticky = "NSEW")
    		else:
    			tk.Button(self, image = self.image_piece[self.i], command = lambda: self.detectCaseClic(self.i), bg = "black", borderwidth = 1).grid(row = L+2, column = C+1, sticky = "NSEW")
    	
    	def detectCaseClic(self, case = "vide"):
    		self.labelVariable.set("Case {case}".format(case = case))


    Ce code fonctionne, mais c'est au niveau de l'action effectuée au clic sur le bouton qui ne marche pas comme prévu...

    Si quelqu'un a une idée, je suis preneur car je n'ai rien trouvé nul part ailleurs sur le web.

    Merci d'avance ! ;)

    EDIT : Je rajoute une petite image du rendu pour aider à conceptualiser :

    -
    Edité par indyteo 23 septembre 2018 à 22:47:47

    • Partager sur Facebook
    • Partager sur Twitter
      24 septembre 2018 à 12:27:08

      Il faut bien comprendre que, lorsqu’à l’intérieur de la fonction lambda, l’interpréteur rencontre self, cette variable n’est pas déclarée et donc il va chercher dans le scope du dessus. Au moment de l’éxecution de la fonction, l’interpréteur va chercher self dans le scope du dessus, et trouve self.i qui contient la dernière valeur que l’on y a mise, et il fait cela pour chaque fonction. Pour ’capturer’ la valeur d’une variable dans le scope de la fonction, il faut faire :

      # ne marche pas
      fs = []
      for i in range(10):
          fs.append(lambda : print(str(i)))
      
      for f in fs: f()
      
      # marche
      fs = []
      for i in range(10):
          fs.append(lambda i=i: print(str(i)))
      
      for f in fs: f()



      -
      Edité par digammaF 24 septembre 2018 à 12:30:40

      • Partager sur Facebook
      • Partager sur Twitter

      typage structurel ftw

        24 septembre 2018 à 17:30:30

        Bonjour,

        merci beaucoup, j'avoue que je ne suis pas très habitué aux fonctions lambda, j'ai été obligé d'en utiliser une pour passer un argument dans la commande de mon bouton, mais sans réellement me pencher dessus et comprendre le fonctionnement.

        Encore merci, j'ai compris mon erreur !

        • Partager sur Facebook
        • Partager sur Twitter

        Tkinter - Boutons dans une boucle

        × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
        × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
        • Editeur
        • Markdown