Tk Event Handling

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

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s