Przypisanie funkcji z argumentami do Button w Tkinter
Normalnie command=
w Button
oczekuje "callback" co oznacza nazwę funkcji bez ()
i bez argumentów - ale czasami jest potrzeba przyspisania funkcji z argumentem i wtedy można do tego użyć lambda
.
command=lambda:function(arg1, arg2, arg3)
import tkinter as tk
def function(text):
print(text)
root = tk.Tk()
button1 = tk.Button(root, text='Yes', command=lambda:function('Yes'))
button1.pack()
button2 = tk.Button(root, text='No', command=lambda:function('No'))
button2.pack()
root.mainloop()
Jeśli musisz podać widget jak argument w tej funkcji to wtedy można to zrobić już po stworzeniu tego widgeta.
button1["command"] = lambda:function(button1)
import tkinter as tk
def function(widget):
print(widget['text'])
root = tk.Tk()
button1 = tk.Button(root, text='Yes')
button1.pack()
button1["command"] = lambda:function(button1)
button2 = tk.Button(root, text='No')
button2.pack()
button2["command"] = lambda:function(button2)
root.mainloop()
Jeśli bedziesz używał lambda
w pętli to wtedy możesz potrzebować
lambda x=text:function(x)
ponieważ normalnie tekst ze zmiennej text
nie jest kopiowany ale jest przypisana tylko referencja/odnośnik do tej zmiennej
i ostatecznie wszystkie Buttons będą miały referencje do tej sameh zmienneh z tą samą wartośći - ostatnią wartością użytą w pętli for
import tkinter as tk
def function(text):
print(text)
root = tk.Tk()
buttons = []
for txt in ('Yes', 'No'):
# problem: all buttons will print "No"
#b = tk.Button(root, text=txt, command=(lambda:function(txt)))
b = tk.Button(root, text=txt, command=(lambda x=txt:function(x)))
b.pack()
buttons.append(b)
root.mainloop()
Jeśli użyjesz bind()
aby przypisać zdarzenie z funkcją do widgetu to wtedy funkcja automatycznie dostanie event
z informacją o widgecie.
import tkinter as tk
def function(event):
#print(event)
print(event.widget['text'])
root = tk.Tk()
button1 = tk.Button(root, text='Yes')
button1.pack()
button1.bind('<Button-1>', function)
button2 = tk.Button(root, text='No')
button2.pack()
button2.bind('<Button-1>', function)
root.mainloop()
BTW: Jeśli checksz tę samą funkcję użyć z command=
in bind()
wtedy należy użyć wartości domyślej - np. None
- aby działała w obu przypadkach
def function(event=None):
ale wtedy nie będzie można wykorzystać wartości przesłanej w event
bo nie zawsze będzie dostępna
Buy a Coffee