def prova(a):
def clk(nn):
print nn
root.destroy()
root = Tk()
n=0
for rg in a:
n+=1
lb2= Button(text=rg)
lb2.bind("<Button-1>",lambda event: (event,clk(n)))
lb2.pack()
root.mainloop()
a=["aaa","bbb","ccc"]
prova(a)
qualunque bottone premo mi restituisce 3
Ma non dovrebbe darmi 1 o 2 o 3 secondo quale premo?
E come dovrei fare?
Tkinter mi sta alquanto antipatico.... (non lo capisco!)
Grazie.
Ultima modifica di maresama il lunedì 26 maggio 2014, 21:06, modificato 1 volta in totale.
Porello Tkinter, è innocente... il tuo primo codice equivale esattamente a questo (ho solo tolto le espressioni lambda):
[code2=python]def prova(a):
def clk(nn):
print nn
root.destroy()
def anonima(event):
return event, clk(n)
root = Tk()
n = 0
for rg in a:
n += 1
lb2 = Button(text=rg)
lb2.bind("<Button-1>", anonima)
lb2.pack()
root.mainloop()
a = ["aaa", "bbb", "ccc"]
prova(a)[/code2]
Come si vede i pulsanti sono bindati solo alla funzione 'anonima', che a sua volta richiama 'clk' passando il valore di 'n' nel momento della chiamata (cioè sempre 3).
Il secondo codice invece non è traducibile in modo semplice, perché di fatto definisci tre funzioni anonime differenti (che chiamano clk con un argomento ben preciso).
In effetti quello del passaggio di valori alle callback è un argomento scomodo, si può risolvere bindando i widget a istanze chiamabili contenenti i dati voluti:
[code2=python]class Ponte:
def __init__(self, callback, nn):
self.callback = callback
self.nn = nn
def __call__(self, event):
self.callback(self.nn)
def prova(a):
def clk(nn):
print nn
root.destroy()
root = Tk()
n = 0
for rg in a:
n += 1
lb2 = Button(text=rg)
lb2.bind("<Button-1>", Ponte(clk, n))
lb2.pack()
root.mainloop()
a = ["aaa", "bbb", "ccc"]
prova(a)[/code2]
Oppure, se non si vuole usare una classe, si può anche usare una clojure:
Ti ringrazio, specialmente per le spiegazioni.
Seguito a dire che, per me, tkinter è ... antipatico!
Ho sempre digerito poco tutta la problematica delle callback per il binding.
Ma se uno capisce il problema... è come prendere un digestivo...!
Grazie nuovamente.
Ciao