Je rencontre un petit problème en essayant de créer des boutons numériques 0-9. Je veux définir 10 boutons pour les nombres de 0 à 9 en boucle unique. Chacun d'eux est censé ajouter sa valeur à self.user_input = tk.StringVar() qui sera imprimé sur l'étiquette. Cliquer sur le bouton 5, le bouton 7 puis le bouton 0 donnera la sortie 570. J'essaie d'utiliser lambda pour créer une commande pour chaque bouton, mais au lieu d'obtenir des valeurs différentes, j'ai 9 partout. Voici mon code:

import tkinter as tk
import tkinter.ttk as ttk

class Gui(tk.Tk):
    def __init__(self):
        super().__init__()
        self.user_input = tk.StringVar()
        tk.Label(self, textvariable=self.user_input).grid()
        self.create_buttons()

    def create_buttons(self):
        for x in range(10):
            ttk.Button(self, text=x, command=lambda: self.user_input.set(self.user_input.get() + str(x))).grid()

app = Gui()
app.mainloop()

Comment puis-je corriger le code ci-dessus pour le faire fonctionner comme prévu (description vers le haut)?

2
Ethr 22 nov. 2019 à 12:49

1 réponse

Meilleure réponse

Mettez la majeure partie de votre code dans une fonction appropriée. Une meilleure pratique est qu'un lambda pour un rappel de widget ne doit jamais appeler qu'une seule fonction. Les lambdas complexes sont difficiles à lire et difficiles à déboguer.

La deuxième partie de la solution consiste à créer une fermeture. L'astuce consiste à faire en sorte que la variable que vous transmettez soit liée au lambda en tant qu'argument par défaut.

Le rappel ressemble à ceci:

def callback(self, number):
    new_value = self.user_input.get() + str(number)
    self.user_input.set(new_value)

La définition de chaque bouton ressemble à ceci:

def create_buttons(self):
    for x in range(10):
        button = ttk.Button(self, text=x, command=lambda number=x: self.callback(number))
        button.grid()

Portez une attention particulière à number=x dans le cadre de la définition lambda. C'est là que la valeur actuelle de x est liée au paramètre number à l'intérieur du lambda.

2
Bryan Oakley 22 nov. 2019 à 13:58