16.9 Tkinter Events
So far, we've seen only
the most elementary kind of event handling: the callbacks performed
on callables installed with the command= option of
buttons and menu entries of various kinds. Tkinter
also lets you install callables to call back when needed to handle a
variety of events. However, Tkinter does not let
you create your own custom events; you are limited to working with
events predefined by Tkinter
itself.
16.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 describing 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
16.9.2 Binding Callbacks to Events
To bind a callback to an event in a widget
w, call
w.bind, describing 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
earlier in this chapter, lets you bind event callbacks to specific
sets of items of a Canvas instance, or to ranges
within a Text instance.
16.9.3 Event Names
Frequently used event names, which are almost all enclosed in angle
brackets, fall into a few categories.
16.9.3.1 Keyboard events
- Key
-
The user clicked any key. The event object's
attribute char tells you which key, but for normal
keys only, not for special keys. The event object's
attribute keysym is equal to attribute
char for letters and digits, is the
character's name for punctuation characters, and is
the key name for special keys, as covered in the next paragraph.
- Special keys
-
Special keys are associated with event names: F1,
F2, ..., up to F12 for function
keys; Left, Right,
Up, Down for arrow keys;
Prior, Next for page-up,
page-down; BackSpace, Delete,
End, Home,
Insert, Print,
Tab, for keys so labeled;
Escape for the key often labeled
Esc; Return for the key often
labeled Enter; Caps_Lock,
Num_Lock, Scroll_Lock for
locking-request keys; Alt_L,
Control_L, Shift_L for the
modifier keys Alt, Ctrl,
Shift (without distinction among the multiple
instances of such modifier keys in a typical keyboard). All of these
event names are placed within angle brackets, like almost all event
names.
- Normal keys
-
Normal keys are associated with event names without surrounding angle
brackets—the only event names to lack such brackets. The event
name of each normal key is just the associated character, such as
'w', '1', or
'+'. Two exceptions are the
Space key, whose event name is
'<space>', and the key associated with the
less-than character, whose event name is
'<less>'.
All key event names can be modified by prefixing
'Alt-', 'Shift-', or
'Control-'. In this case, the whole event name
does always have to be surrounded with
'<...>'. For example,
'<Control-Q>' and
'<Alt-Up>' name events corresponding to
normal or special keys with modifiers.
16.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 (there is no mouse event for mouse motion without
pressing a button, except for 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.
16.9.4 Event-Related Methods
Each widget
w supplies the following event-related
methods.
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.
w.bind_all(event_name,callable[,'+'])
|
|
w.bind_all(event_name,callable)
sets callable as the callback for
event_name on any widget of the
application, whatever widget w you call
the method on.
w.bind_all(event_name,callable,'+')
adds callable to the previous bindings for
event_name on any widget.
Removes all callbacks for event_name on
w.
Removes all callbacks for event_name on
any widget, previously set by calling method
bind_all on any widget.
16.9.5 An Events Example
The following example shows how to detect key presses and
mouse-button presses and releases using the
bind_all method:
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):
msg = 'Mouse event %s' % eventname
L.config(text=msg)
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( )
16.9.6 Other Callback-Related Methods
Each widget w supplies the following other
callback-related methods.
w.after(ms,callable,*args)
|
|
Starts a timer that calls
callable(*args)
about ms milliseconds from now. Returns an
ID that you can pass to after_cancel to cancel the
timer. The timer is one-shot: for a function to be called
periodically, the function itself must call after
to install itself as a callback again.
Cancels the timer identified by id.
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 shows how to use 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( )
The kind of polling that method after lets you
establish is an important Tkinter technique.
Several Tkinter widgets have no callbacks to let
you know about user actions on them, so if you want to track such
actions in real-time, polling may be your only option. For example,
here's how to use polling established 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)
s['command'] = L.yview
L['yscrollcommand'] = s.set
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( )
|