Bartłomiej 'furas' Burek
furas.pl
# prywatne notatki - Python, Linux, Machine Learning, etc.

Assign function with arguments to Button in Tkinter

Normally command= in Button expects "callback" - it means function's name without () and without arguments - but sometimes it is needed to assign function with argument and then you can use lambda to do this.

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()

If you want to use widget as argument in this function then you can do it after creating widget.

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()

If you will use lambda in loop then you many need

lambda x=text:function(x)

because normally it doesn't copy text from text but it assigns reference to variable text and later all buttons have reference to the same variable with the same value (last value from for-loop)

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()

If you use bind() to assign event with function to widget then function automatically get event with information about widget

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: if you want to use use the same function with command= and bind() then you have to use default value - ie. None

def function(event=None):

but you will not use values send in event because it will not be avaliable in every execution.

Książki: python-dla-kazdego-podstawy-programowania python-wprowadzenie python-leksykon-kieszonkowy python-receptury python-programuj-szybko-i-wydajnie python-projekty-do-wykorzystania black-hat-python-jezyk-python-dla-hackerow-i-pentesterow efektywny-python-59-sposobow-na-lepszy-kod tdd-w-praktyce-niezawodny-kod-w-jezyku-python aplikacje-internetowe-z-django-najlepsze-receptury