GUIs with Tkinter
Tutorials Applied Visualizaton
Summer Term 2010
Why GUI?
Part III - GUIs with Tkinter
Because this is nice
[20:51:11]
[20:51:11]
[20:51:11]
[20:51:11]
[20:51:11]
[20:51:11]
[20:51:11]
[20:51:11]
[20:51:11]
...
lyra:~
lyra:~
lyra:~
lyra:~
lyra:~
lyra:~
lyra:~
lyra:~
lyra:~
$
$
$
$
$
$
$
$
$
python
python
python
python
python
python
python
python
python
dosomething.py
dosomething.py
dosomething.py
dosomething.py
dosomething.py
dosomething.py
dosomething.py
dosomething.py
dosomething.py
file1
file2
file3
file4
file5
file6
file7
file8
file9
GUIs with Tkinter
GUIs with Tkinter
Why GUI?
Why GUI?
But this is nicer
Or the visualization way
[20:51:11]
[20:51:11]
[20:51:11]
[20:51:11]
[20:51:11]
[20:51:11]
[20:51:11]
[20:51:11]
[20:51:11]
[20:51:11]
[20:51:11]
[20:51:11]
[20:51:11]
[20:51:11]
[20:51:11]
[20:51:11]
[20:51:11]
[20:51:11]
[20:51:11]
[20:51:11]
[20:51:11]
lyra:~
lyra:~
lyra:~
lyra:~
lyra:~
lyra:~
lyra:~
lyra:~
lyra:~
lyra:~
lyra:~
lyra:~
lyra:~
lyra:~
lyra:~
lyra:~
lyra:~
lyra:~
lyra:~
lyra:~
lyra:~
$ python doisosurface.py 50
$
$
$
$
$
$
$
$
$ python doisosurface.py 900
$
$
$
$
$
$
$
$
$ python doisosurface.py 1250
$
$
GUIs with Tkinter
GUIs with Tkinter
Why GUI?
Tkinter
Or the visualization way
Python interface for Tk
Tk is a library for rapid GUI scripting
Easy to use
Good integration in VTK
Widely available
GUIs with Tkinter
GUIs with Tkinter
Tkinter comes as module for Python
Insertion - Python classes
import Tkinter
The expressions
from Tkinter import *
root = Tk()
Tkinter.wantobjects = 0 # WINDOWS users
btn = Button(root, text="Quit", command=root.quit)
def say_hi():
print "Hello Class"
root = Tk()
btn = Button(root, text="Quit", command=root.quit)
btn.pack()
Classes have the usual meaning in Python
btn2 = Button(root, text="Say Hi", command=say_hi)
btn2.pack()
instantiate Python classes
Definition of objects with attributes and methods
In order to encapsulate and hide behavior
root.mainloop()
GUIs with Tkinter
GUIs with Tkinter
Insertion - Python classes
Tk GUIs are built hierarchical
Instantiation uses function syntax
root = Tk()
root = Tk()
btn = Button(root, text="Quit", command=root.quit)
You need one root window
Attributes and methods are referenced with the
. operator
btn.pack()
Does not have to be called root, but it usually is
Then you can create other elements as children of that
root window (e.g. a Button)
btn = Button(root, text="Quit", command=root.quit)
someotherclass.value = 10
Syntax is quite similar to that of accessing module
contents
GUIs with Tkinter
10
GUIs with Tkinter
Tk GUIs are built hierarchical
Tk GUIs are built hierarchical
Root Window
(Tk())
Of course you can have more than
one hierarchy
Toplevel
Frame
Button
Button
Root
Window
Frame
...
Button
11
Frame
Button
Button
Button
...
...
12
GUIs with Tkinter
GUIs with Tkinter
The mainloop() method
The event loop in GUI programs
Last call you issue actively in the entry method
Starts message processing
From there, any GUI application is event driven!
There is usually only one mainloop per thread
(i.e. in our case only one mainloop at all)
That is why we must differentiate between the Root
window (Tk()) and another Toplevel window
Your script
Command Function
(aka Event Handler)
13
GUIs with Tkinter
GUIs with Tkinter
Widgets
Widgets
Tkinter supports 15 core widgets
14
Button
Canvas
Checkbutton
Entry
Frame
Label
Listbox
Menu
Menubutton
Tkinter supports 15 core widgets
15
Message
Radiobutton
Scale
Scrollbar
Text
Toplevel
16
GUIs with Tkinter
GUIs with Tkinter
Widgets
Widgets
Use all the same configuration interface
Works by keyword arguments
w = widgetclass(parent, option=value, ...)
The cget method lets you get an option value
You can use a dictionary interface
>>> w["text"]
'button'
>>> w["text"] = "hello"
>>>
w = Button(root, text="button", command=hello)
w.cget('command')
>>> '225192hello'
w.cget('text')
>>> 'button'
The keys() method works as you would expect
>>> w.keys()
['activebackground', 'activeforeground', 'anchor', 'background', 'bd',
'bg', 'bitmap', 'borderwidth', 'command', 'compound', 'cursor', 'default',
'disabledforeground', 'fg', 'font', 'foreground', 'height',
'highlightbackground', 'highlightcolor', 'highlightthickness', 'image',
'justify', 'overrelief', 'padx', 'pady', 'relief', 'repeatdelay',
'repeatinterval', 'state', 'takefocus', 'text', 'textvariable',
'underline', 'width', 'wraplength']
>>>
17
GUIs with Tkinter
GUIs with Tkinter
Widgets
Widgets
The pack() method
>>> w.pack()
Pack has some useful options
>>> w.pack(side=LEFT, fill=BOTH)
Tells the widget to size itself fit to the given contents
and make itself visible
Consequence
18
If you forget to call pack() you wont see your widget!
19
side specifies which side to pack the widget against
fill specifies if the widget should occupy all the space
given to it by its parent
expand specifies whether the widget is allowed to
expand in order to fill up empty space
20
GUIs with Tkinter
GUIs with Tkinter
Commonly used widgets
Commonly used widgets
Button
The probably most widely used control in the world
Most important options
The method to call when the button is hit
...
text
A surface area you can draw on
window = Toplevel(width=800, height=600)
tfCanvas = Canvas(ctrlWindow, width=400, height=250, relief=RAISED,
selectbackground='grey')
tfCanvas.pack(anchor=NW, side=TOP)
command
Canvas
tfCanvas.create_line(xs,ys,xe,ye, fill=black)
The text on the button
21
GUIs with Tkinter
GUIs with Tkinter
Commonly used widgets
Commonly used widgets
Canvas - has many methods
create_arc
create_bitmap
create_polygon
...
Checkbutton
Represents a variable that can have two distinct values
Needs a Tkinter variable to work with
var = IntVar() # this is Tkinters way of saying: I want an int
c = Checkbutton(root, text=Hello, variable=var)
c.pack()
Items can be named, queried and so on
22
Details when we need them
If you are interested anyway, see the tutorial
Default is: Button selected, var = 1, 0 otherwise
You can query the variable like this
value = var.get()
23
24
GUIs with Tkinter
GUIs with Tkinter
Commonly used widgets
Commonly used widgets
Checkbutton
Has a command option that is called when the state
changes
Entry
Represents a single line text entry field
root = Tk()
var = IntVar() # this is Tkinters way of saying: I want an int
e = Entry(root, width=55)
e.pack()
def say_hello():
print Hello, var.get()
def say_hello():
print e.get()
c = Checkbutton(root, text=Hello, command=say_hello, variable=var)
c.pack()
b = Button(root,text="Hello", command=say_hello)
b.pack()
qb = Button(root, text="Quit", command=root.quit)
qb.pack()
root.mainloop()
25
GUIs with Tkinter
GUIs with Tkinter
Commonly used widgets
Commonly used widgets
Label
26
Listbox
Displays text or an image
root = Tk()
l = Label(root, text="This is rather boring, I suppose")
l.pack()
Displays a list of alternatives
Very useful for selection purposes
lb = Listbox(root, selectmode=MULTIPLE)
for i in range(10):
lb.insert(END, str(i))
qb = Button(root, text="Quit", command=root.quit)
qb.pack()
lb.pack()
root.mainloop()
def say_hello():
print str(lb.curselection())
b = Button(root,text="Hello", command=say_hello)
b.pack()
qb = Button(root, text="Quit", command=root.quit)
qb.pack()
root.mainloop()
27
28
GUIs with Tkinter
GUIs with Tkinter
Commonly used widgets
Commonly used widgets
Radiobutton
root = Tk()
MODES = [
("Monochrome", "1"),
("Grayscale", "L"),
("True color", "RGB"),
("Color separation", "CMYK"),
]
Used to select one out of several alternatives
Similar to a checkbutton, but
For correct behaviour, all buttons in a group have to
point to the same variable
v = StringVar()
v.set("L") # initialize
for text, mode in MODES:
b = Radiobutton(root, text=text, variable=v, value=mode)
b.pack(anchor=W)
v = IntVar()
Radiobutton(root, text="One", variable=v, value=1).pack(anchor=W)
Radiobutton(root, text="Two", variable=v, value=2).pack(anchor=W)
def say_hello():
print v.get()
b = Button(root,text="Hello", command=say_hello)
b.pack()
qb = Button(root, text="Quit", command=root.quit)
qb.pack()
root.mainloop()
29
GUIs with Tkinter
GUIs with Tkinter
Commonly used widgets
Commonly used widgets
Scale
30
The scale widget allows you to set a numerical value by
drawing a slider
Text
Used to enter multiline text
root = Tk()
t = Text(root, width=100, height=50)
t.pack()
root = Tk()
def dragged(event):
print s.get()
def get_value():
v = t.get(1.0,END)
print v
s = Scale(root, orient=HORIZONTAL, from_=10, to_=100, label="Test", command=dragged)
s.pack()
b = Button(root, text="Get Value", fg="red", command=get_value)
b.pack()
def get_value():
print s.get()
qb = Button(root, text="Quit", command=root.quit)
qb.pack()
b = Button(root, text="Get Value", fg="red", command=get_value)
b.pack()
root.mainloop()
qb = Button(root, text="Quit", command=root.quit)
qb.pack()
root.mainloop()
31
32
GUIs with Tkinter
GUIs with Tkinter
Commonly used widgets
Commonly used widgets
Text
Example 2
Toplevel
A toplevel finally can be used to create more windows
root = Tk()
root = Tk()
t = Text(root, width=100, height=50)
t.pack()
tl = Toplevel()
def execute():
chunk = t.get(1.0,END)
obj = compile(chunk, '<string>', 'exec')
exec obj
t = Text(tl, width=100, height=50)
t.pack()
b = Button(root, text="Execute", fg="red", command=execute)
b.pack()
def get_value():
v = t.get(1.0,END)
print v
qb = Button(root, text="Quit", command=root.quit)
qb.pack()
b = Button(root, text="Get Value", fg="red", command=get_value)
b.pack()
root.mainloop()
qb = Button(root, text="Quit", command=root.quit)
qb.pack()
root.mainloop()
33
GUIs with Tkinter
GUIs with Tkinter
Commonly used widgets
Events and Bindings
Not discussed
34
Frame
Menu
Menubutton
Message
Scrollbar
Important, since you not only want to react to button
clicks or selections but also
Mouse clicks anywhere
Mouse movement
Keyboard input
We wont need them
If you are interested, refer to the documentation
35
36
GUIs with Tkinter
GUIs with Tkinter
Events and Bindings
Events and Bindings
You bind events to widgets using bind()
Event attributes
event.widget
event.x
event.y
event.x_root
event.y_root
event.char
event.keysym
event.keycode
event.num
event.width
event.height
event.type
widget.bind(event, eventhandler)
Where event handler has the form
def eventhandler(event):
#do something
Whenever event happens on the widget, the event
handler gets called and gets passed an event structure
#
#
#
#
the widget generating the event
current mouse x position in pixels
current mouse y position in pixels
current position relative to upper left screen corner
#
#
#
#
#
#
#
the character code (keyboard event)
key symbol (keyboard event)
key code (keyboard event)
the button number (mouse click events)
new with of the widget (resize event)
new height of the widget (resize event)
event type sent
37
38
GUIs with Tkinter
GUIs with Tkinter
Events and Bindings
Events and Bindings
from Tkinter import *
root = Tk()
Event types
<Button-1>, <Button-2>, ...
Mouse button X pressed
<B1-Motion>, <B2-Motion>, ...
Mouse moved while button X pressed
<ButtonRelease-1>, <ButtonRelease-2>, ...
Mouse button X released
<Double-Button-1>, <Double-Button-2>, ...
Can you guess that one? :-)
<Enter>
Mouse pointer entered the widget area
<Leave>
Mouse pointer left the widget area
def eventtest(event):
print "Mouse: " , str( (event.x,event.y) )
tl = Toplevel()
t = Text(tl, width=100, height=50)
t.pack()
t.bind("<Button-1>", eventtest)
def get_value():
v = t.get(1.0,END)
print v
b = Button(root, text="Get Value", fg="red", command=get_value)
b.pack()
qb = Button(root, text="Quit", command=root.quit)
qb.pack()
root.mainloop()
39
40
GUIs with Tkinter
GUIs with Tkinter
Events and Bindings
Events and Bindings
Event types
<Return>
User pressed the return key
Can use BackSpace, Tab, Shift_L, Shift_R, Control_L, Alt_L, and so on
<Key>
User pressed any key (query via event.char)
a, b, c, ...
User pressed a, b, c ... most printable characters can be used as is
<Shift-Up>
User pressed Shift and the UP arrow
Most key events can be prefixed by Alt, Shift and Control
Bindings
The bind() method creates an instance binding
Event handlers are executed on a specific widget instance
You can also bind at toplevel, class or application level
Toplevel uses bind() on toplevel window
On a class of widgets use bind_class()
But, dont do that, really...
For application level use bind_all() on the root window
41
GUIs with Tkinter
GUIs with Tkinter
Events and Bindings
42
Comprehensive tutorial and reference
Bindings
root = Tk()
def eventtest(event):
print "Mouse: " , str( (event.x,event.y) )
http://www.pythonware.com/library/tkinter/
introduction/index.htm
tl = Toplevel()
t = Text(tl, width=100, height=50)
t.pack()
root.bind_all("<Enter>", eventtest)
def get_value():
v = t.get(1.0,END)
print v
b = Button(root, text="Get Value", fg="red", command=get_value)
b.pack()
qb = Button(root, text="Quit", command=root.quit)
qb.pack()
root.mainloop()
43
44