All GUI programs need a way to respond to user interactions. The Tk GUI toolkit provided in Python provides us with a number of different ways to respond to user interactions. Let’s look at a few different ways we can make buttons respond to user events.
Pass a Function
Since Python considers functions to be objects, we can just pass a function to the event handler.
def click():
print('Clicked')
root = Tk()
Button(root, text='Click Me', command=click).pack()
root.mainloop()
Use a Lambda
Lamdas are another popular way to express event handling code.
root = Tk()
Button(root, text='Click Me', command=(lambda: print('Clicked'))).pack()
root.mainloop()
Use a Class
Many programs construct GUIs using Pythons OOP capabilities. As such, we can bind a class method to the event handler also.
class MyClass:
def __init__(self, root):
self.button = Button(root, text='Class', command=self.command).pack()
def command(self):
print('Class handler')
root = Tk()
MyClass(root)
root.mainloop()
Override the __call__ method
We can also construct classes that overload the __call__ operator. Doing so is useful when we need to pass complex information along to an event handler.
class MyCallable:
def __init__(self):
self.message = '__call__ handler'
def __call__(self):
print(self.message)
root=Tk()
Button(root, text='Callable', command=MyCallable()).pack()
root.mainloop()
Event Binding
We can also make direct calls to Tk
def print_me():
print('binding')
root = Tk()
w = Button(root, text='Binding')
w.pack()
w.bind('<Button-1>, print_me)
root.mainloop()
Complete Program
Below is a complete program that demonstrates all of the above patterns.
import sys
from tkinter import *
def write():
print('Function call')
class HelloClass:
def __init__(self, root):
self.button = Button(root, text='Class', command=self.command).pack(side=LEFT, fill=X)
def command(self):
print('Class handler')
class Callable:
def __init__(self):
self.message = '__call__ handler'
def __call__(self):
print(self.message)
def printMe(event):
print('Double click to quit')
def quit(event):
sys.exit()
if __name__ == '__main__':
root = Tk()
Button(root, text='Function', command=write).pack(side=LEFT, fill=X)
Button(root, text='Lambda', command=(lambda: print('Labmda call'))).pack(side=LEFT, fill=X)
HelloClass(root)
Button(root, text='Callable', command=Callable()).pack(side=LEFT, fill=X)
w = Button(root, text='Binding')
w.pack(side=LEFT, fill=X)
w.bind('<Button-1>', printMe)
w.bind('<Double-1>', quit)
root.mainloop()