Pagina 1 di 1
risolto - Tkinter - uso bottoni
Inviato: domenica 11 maggio 2014, 9:29
da maresama
Con:
Codice: Seleziona tutto
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.
Re: Tkinter - uso bottoni
Inviato: domenica 11 maggio 2014, 19:33
da maresama
e perchè così funziona?
Codice: Seleziona tutto
def prova(a):
def clk(nn):
print nn
root.destroy()
root = Tk()
rg=a[0]
lb2= Button(text=rg)
lb2.bind("<Button-1>",lambda event: (event,clk(1)))
lb2.pack()
rg=a[1]
lb2= Button(text=rg)
lb2.bind("<Button-1>",lambda event: (event,clk(2)))
lb2.pack()
rg=a[2]
lb2= Button(text=rg)
lb2.bind("<Button-1>",lambda event: (event,clk(3)))
lb2.pack()
root.mainloop()
a=["aaa","bbb","ccc"]
prova(a)
Qualcuno ci capisce qualcosa?
Re: Tkinter - uso bottoni
Inviato: lunedì 12 maggio 2014, 0:24
da Claudio_F
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:
[code2=python]def ponte(callback, nn):
def new_function(event):
callback(nn)
return new_function
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]
Re: Tkinter - uso bottoni
Inviato: lunedì 12 maggio 2014, 21:50
da maresama
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