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