tkinter crea pulsanti in per passare gli argomenti del comando di passaggio

Sto cercando di creare pulsanti in tkinter all’interno di un ciclo for. E con ogni ciclo passa il valore di conteggio i come argomento nel valore di comando. Quindi, quando la funzione viene chiamata dal valore di comando, posso dire quale pulsante è stato premuto e agire di conseguenza. Il problema è, diciamo che len è 3, creerà 3 pulsanti con titoli “Gioco 1” attraverso “Gioco 3” ma quando uno qualsiasi dei pulsanti viene premuto il valore stampato è sempre 2, l’ultima iterazione. Quindi sembra che i pulsanti vengano creati come entity framework separate, ma il valore i negli argomenti del comando sembra essere lo stesso. Ecco il codice:

def createGameURLs(self): self.button = [] for i in range(3): self.button.append(Button(self, text='Game '+str(i+1),command=lambda:self.open_this(i))) self.button[i].grid(column=4, row=i+1, sticky=W) def open_this(self, myNum): print(myNum) 

C’è un modo per ottenere il valore corrente i, su ogni iterazione, per attaccare con quel particolare pulsante?

    Cambia il tuo lambda in lambda i=i: self.open_this(i) .

    Questo può sembrare magico, ma ecco cosa sta succedendo. Quando si utilizza quella lambda per definire la propria funzione, la chiamata open_questa non ottiene il valore della variabile i nel momento in cui si definisce la funzione. Invece, fa una chiusura, che è una specie di nota a se stessa che dice “Dovrei cercare quale sia il valore della variabile i nel momento in cui sono chiamato “. Naturalmente, la funzione viene chiamata dopo che il ciclo è finito, quindi in quel momento sarò sempre uguale all’ultimo valore del ciclo.

    L’uso del trucco i=i fa sì che la tua funzione memorizzi il valore corrente di i nel momento in cui viene definito il tuo lambda, invece di aspettare il valore di i dopo.

    Questo è il modo in cui le chiusure funzionano in python. Mi sono imbattuto in questo problema una volta. Potresti usare functools.partial per questo.

     for i in range(3): self.button.append(Button(self, text='Game '+str(i+1), command=partial(self.open_this, i)))