Forum Programmation.python tk: boutons, actions et passage d'argument avec lambda

Posté par (page perso) . Licence CC by-sa.
1
16
jan.
2019

Bonjour,
Je suis en train de faire une petite application graphique avec python et tk.

Je crée un canvas sur lequel je place quatre boutons à l'aide d'une boucle. Pour cela, je crée d'abord des tableaux, dans lequel je mettrai ensuite les objets boutons. Pour que chaque bouton puisse avoir une action différente, je souhaite donner un argument dans la commande de ceux-ci. Le problème que j'ai, c'est qu'avec mon code, tous les boutons ont la même action (j=4), et je ne comprend pas pourquoi…

Voici mon code simplifié, pour tester:

#!/usr/bin/python3
import os, sys

pathname=sys.path[0]
bgcolor        = "lightgrey"
# Couleur des colonnes, autant que le nombre désiré
cols_colors = ["lightblue","lightgrey","lightgreen","orange"]

class Application(object):
    def __init__(self):
        """Constructeur de la fenêtre principale"""
        self.root =Tk()
        self.root.title('compter')

        # Tableaux pour les boutons
        self.btn=[]
        self.fen_btn=[]

        self.slideshow()

        self.root.bind("<F11>", self.toggle_fullscreen)
        self.root.bind("<Escape>", self.end_fullscreen)
        self.state = False

        self.toggle_fullscreen()
        self.root.focus_set()          # prendre le focus
        self.root.mainloop()

    def toggle_fullscreen(self, event=None):
        self.state = not self.state  # Just toggling the boolean
        self.root.attributes("-fullscreen", self.state)
        return "break"

    def end_fullscreen(self, event=None):
        if self.state == False :
            self.root.quit()                    
        self.state = False
        self.root.attributes("-fullscreen", False)
        return "break"

    def slideshow(self):
        """Canevas avec colonnes"""
        self.screen_w = self.root.winfo_screenwidth()
        self.screen_h = self.root.winfo_screenheight()

        # Créer le canevas
        self.can = Canvas(self.root, width=self.screen_w, height =self.screen_h, bg =bgcolor)
        self.can.grid(row =1, column =1, columnspan =1, pady =0, padx =0)

        # Les colonnes et boutons
        j=0
        for i in cols_colors:
            self.can.create_rectangle(self.screen_w//len(cols_colors)*j, 70, self.screen_w//len(cols_colors)*(1+j), self.screen_h, fill =i, width =2)
            # Le bug est probablement dans les deux lignes suivantes
            self.btn.append(Button(self.can, text="OK", bg=bgcolor, command = lambda: self.valider(j)))
            self.fen_btn.append(self.can.create_window(self.screen_w//8*(2*j+1), 300+70+50, window =self.btn[j]))
            j+=1

    def valider(self,col):
        '''Valider une colonne'''
        print("colonne: ", col)      

    def stop(self):
        self.root.quit()

# Programme principal :
if __name__ == '__main__':
    from tkinter import *
    f = Application()       # instanciation de l'objet application

Merci pour votre aide!

Suivre le flux des commentaires

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