Previous Page
Next Page

17.9. Tkinter Events

So far, we've seen only one kind of event handling: callbacks performed on callables set with the command= option of buttons and menu entries. Tkinter also lets you set callables to handle a variety of events. Tkinter does not let you create custom events: you are limited to working with events predefined by Tkinter itself.

17.9.1. The Event Object

General event callbacks must accept one argument event that is a Tkinter event object. Such an event object has several attributes that describe the event:


char

A single-character string that is the key's code (only for keyboard events)


keysym

A string that is the key's symbolic name (only for keyboard events)


num

Button number (only for mouse-button events); 1 and up


x, y

Mouse position, in pixels, relative to the upper-left corner of the widget


x_root y_root

Mouse position, in pixels, relative to the upper-left corner of the screen


widget

The widget in which the event has occurred

17.9.2. Binding Callbacks to Events

To bind a callback to an event in a widget w, call w.bind and describe the event with a string, usually enclosed in angle brackets ('<...>'). The following example prints 'Hello World' each time the user presses the Enter key:

from Tkinter import *

root = Tk( )
def greet(*ignore): print 'Hello World'
root.bind('<Return>', greet)
root.mainloop( )

Method tag_bind of classes Canvas and Text (covered in tag_bind on page 430 and tag_bind on page 437) binds event callbacks to sets of items of a Canvas instance, or ranges within a Text instance.

17.9.3. Event Names

Common event names, almost all of which are enclosed in angle brackets, fall into a few categories.

17.9.3.1. Keyboard events

Key

The user clicked any key. The event object's attribute char tells you which key, for normal keys only. Attribute keysym is equal to char for letters and digits, the character's name for punctuation, and the key's name for special keys.


Special keys

Special keys have event names: F1, F2, and up are function keys; Left, Right, Up, and Down are arrows; Prior and Next are page-up and page-down; BackSpace, Delete, End, Home, Insert, Print, and Tab are the keys so labeled; Escape is the key labeled Esc; Return is the key labeled Enter; Caps_Lock, Num_Lock, and Scroll_Lock are lock-request keys; and Alt_L, Control_L, Shift_L are the modifier keys Alt, Ctrl, Shift (without distinction among multiple instances of such modifier keys in a keyboard). All of these event names are placed within angle brackets, like almost all event names.


Normal keys

Normal keys have event names without surrounding angle bracketsthe only event names that lack brackets. The event name of each normal key is the key's character, such as 'w', '1', or '+'. Exceptions are the Space key, with event name '<space>', and the key of the less-than character, with event name '<less>'.

Key names can be modified by the prefixes 'Alt-', 'Shift-', and 'Control-'. In this case, the event name is always surrounded with '<...>'; for example, '<Control-Q>' and '<Alt-Up>'.

17.9.3.2. Mouse events

Button-1 Button-2 Button-3

The user pressed the left, middle, or right mouse-button. A two-button mouse produces only events Button-1 and Button-3, since it has no middle button.


B1-Motion B2-Motion B3-Motion

The user moved the mouse while pressing the left, middle, or right mouse button (mouse motion without pressing a button can produce only Enter and Leave).


ButtonRelease-1 ButtonRelease-2 ButtonRelease-3

The user released the left, middle, or right mouse button.


Double-Button-1 Double-Button-2 Double-Button-3

The user double-clicked the left, middle, or right mouse button (such an action also generates Button-1, Button-2, or Button-3 before the double-click event).


Enter

The user moved the mouse so that the mouse entered the widget.


Leave

The user moved the mouse so that the mouse exited the widget.

17.9.4. Event-Related Methods

Each widget w supplies the following event-related methods.

bind

w.bind(event_name,callable[,'+'])

w.bind(event_name,callable) sets callable as the callback for event_name on w. w.bind(event_name,callable,'+') adds callable to the previous bindings for event_name on w.

bind_all

w.bind_all(event_name,callable[,'+'])

w.bind_all(event_name,callable) sets callable as the callback for event_name on all widgets. w.bind_all(event_name,callable,'+') adds callable to the previous bindings for event_name on all widgets.

unbind

w.unbind(event_name)

Removes all callbacks for event_name on w.

unbind_all

w.unbind_all(event_name)

Removes all callbacks for event_name on any widget, as set by bind_all.


17.9.5. An Events Example

The following example detects key and mouse events with bind_all:

import Tkinter from Tkinter import *

root = Tk( )
prompt='Click any button, or press a key'
L = Label(root, text=prompt, width=len(prompt))
L.pack( )

def key(event):
    if event.char==event.keysym:
        msg ='Normal Key %r' % event.char
    elif len(event.char)==1:
        msg ='Punctuation Key %r (%r)' % (event.keysym, event.char)
    else:
        msg ='Special Key %r' % event.keysym
    L.config(text=msg)
L.bind_all('<Key>', key)

def do_mouse(eventname):
    def mouse_binding(event):
        L.config(text='Mouse event %s' % eventname)
    L.bind_all('<%s>'%eventname, mouse_binding)
for i in range(1,4):
    do_mouse('Button-%s'%i)
    do_mouse('ButtonRelease-%s'%i)
    do_mouse('Double-Button-%s'%i)

root.mainloop( )

17.9.6. Other Callback-Related Methods

Each widget w supplies the following other callback-related methods.

after

w.after(ms,callable,*args)

Starts a timer to call callable(*args) ms milliseconds from now. Returns an ID that you can pass to after_cancel to cancel the timer. The timer is one-shot: to call a function periodically, the function itself must call after to install itself again.

after_cancel

w.after_cancel(id)

Cancels the timer identified by id.

after_idle

w.after_idle(callable,*args)

Registers a callback to callable(*args) to be performed when the event loop is idle (i.e., when all pending events have been processed).


The following example uses after to implement a simple digital clock:

import Tkinter import time

curtime = ''
clock = Tkinter.Label( )
clock.pack( )

def tick( ):
    global curtime
    newtime = time.strftime('%H:%M:%S')
    if newtime != curtime:
        curtime = newtime
        clock.config(text=curtime)
    clock.after(200, tick)
tick( )
clock.mainloop( )

Method after is crucially important. Many widgets have no callbacks to let you know about user actions on them; to track such actions, polling is the only option. For example, here's how to poll with after to track a Listbox selection in real time:

import Tkinter

F1 = Tkinter.Frame( )
s = Tkinter.Scrollbar(F1)
L = Tkinter.Listbox(F1)
s.pack(side=Tkinter.RIGHT, fill=Tkinter.Y)
L.pack(side=Tkinter.LEFT, fill=Tkinter.Y, yscrollcommand=s.set)
s['command'] = L.yview for i in range(30): L.insert(Tkinter.END, str(i))
F1.pack(side=Tkinter.TOP)

F2 = Tkinter.Frame( )
lab = Tkinter.Label(F2)
def poll( ):
    lab.after(200, poll)
    sel = L.curselection( )
    lab.config(text=str(sel))
lab.pack( )
F2.pack(side=Tkinter.TOP)

poll( )
Tkinter.mainloop( )


Previous Page
Next Page