Slides From INF3331 Lectures - Basic GUI Programming in Python
Slides From INF3331 Lectures - Basic GUI Programming in Python
August 2011
°
c www.simula.no/˜hpl
Simple GUI programming with Python – p. 2/62
Contents
°
c www.simula.no/˜hpl
Simple GUI programming with Python – p. 3/62
GUI toolkits callable from Python
°
c www.simula.no/˜hpl
Simple GUI programming with Python – p. 4/62
Discussion of GUI toolkits
°
c www.simula.no/˜hpl
Simple GUI programming with Python – p. 6/62
Tkinter, Pmw and Tix
°
c www.simula.no/˜hpl
Simple GUI programming with Python – p. 7/62
Scientific Hello World GUI
°
c www.simula.no/˜hpl
Simple GUI programming with Python – p. 8/62
The code (1)
#!/usr/bin/env python
from Tkinter import *
import math
root = Tk() # root (main) window
top = Frame(root) # create frame (good habit)
top.pack(side=’top’) # pack frame in main window
hwtext = Label(top, text=’Hello, World! The sine of’)
hwtext.pack(side=’left’)
r = StringVar() # special variable to be attached to widgets
r.set(’1.2’) # default value
r_entry = Entry(top, width=6, relief=’sunken’, textvariable=r)
r_entry.pack(side=’left’)
°
c www.simula.no/˜hpl
Simple GUI programming with Python – p. 9/62
The code (2)
°
c www.simula.no/˜hpl
Simple GUI programming with Python – p. 10/62
Structure of widget creation
Variables can be tied to the contents of, e.g., text entries, but only
special Tkinter variables are legal: StringVar, DoubleVar,
IntVar
°
c www.simula.no/˜hpl
Simple GUI programming with Python – p. 11/62
The event loop
°
c www.simula.no/˜hpl
Simple GUI programming with Python – p. 12/62
Binding events
°
c www.simula.no/˜hpl
Simple GUI programming with Python – p. 13/62
Packing widgets
°
c www.simula.no/˜hpl
Simple GUI programming with Python – p. 14/62
Packing from top to bottom
°
c www.simula.no/˜hpl
Simple GUI programming with Python – p. 15/62
Lining up widgets with frames
°
c www.simula.no/˜hpl
Simple GUI programming with Python – p. 16/62
Code for middle frame
°
c www.simula.no/˜hpl
Simple GUI programming with Python – p. 17/62
Change fonts
°
c www.simula.no/˜hpl
Simple GUI programming with Python – p. 18/62
Add space around widgets
°
c www.simula.no/˜hpl
Simple GUI programming with Python – p. 19/62
Changing colors and widget size
quit_button = Button(top,
text=’Goodbye, GUI World!’,
command=quit,
background=’yellow’,
foreground=’blue’)
quit_button.pack(side=’top’, pady=5, fill=’x’)
# fill=’x’ expands the widget throughout the available
# space in the horizontal direction
°
c www.simula.no/˜hpl
Simple GUI programming with Python – p. 20/62
Translating widgets
°
c www.simula.no/˜hpl
Simple GUI programming with Python – p. 21/62
Learning about pack
$scripting/src/tools/packdemo.tcl
°
c www.simula.no/˜hpl
Simple GUI programming with Python – p. 22/62
The grid geometry manager
°
c www.simula.no/˜hpl
Simple GUI programming with Python – p. 23/62
Basic grid options
°
c www.simula.no/˜hpl
Simple GUI programming with Python – p. 24/62
Example: Hello World GUI with grid
°
c www.simula.no/˜hpl
Simple GUI programming with Python – p. 25/62
The sticky option
°
c www.simula.no/˜hpl
Simple GUI programming with Python – p. 26/62
Configuring widgets (1)
°
c www.simula.no/˜hpl
Simple GUI programming with Python – p. 27/62
Configuring widgets (2)
See
$scripting/src/py/gui/hwGUI9_novar.py
°
c www.simula.no/˜hpl
Simple GUI programming with Python – p. 28/62
GUI as a class
°
c www.simula.no/˜hpl
Simple GUI programming with Python – p. 29/62
Creating the GUI as a class (1)
class HelloWorld:
def __init__(self, parent):
# store parent
# create widgets as in hwGUI9.py
def quit(self, event=None):
# call parent’s quit, for use with binding to ’q’
# and quit button
def comp_s(self, event=None):
# sine computation
root = Tk()
hello = HelloWorld(root)
root.mainloop()
°
c www.simula.no/˜hpl
Simple GUI programming with Python – p. 30/62
Creating the GUI as a class (2)
class HelloWorld:
def __init__(self, parent):
self.parent = parent # store the parent
top = Frame(parent) # create frame for all class widgets
top.pack(side=’top’) # pack frame in parent’s window
# create frame to hold the first widget row:
hwframe = Frame(top)
# this frame (row) is packed from top to bottom:
hwframe.pack(side=’top’)
# create label in the frame:
font = ’times 18 bold’
hwtext = Label(hwframe, text=’Hello, World!’, font=font)
hwtext.pack(side=’top’, pady=20)
°
c www.simula.no/˜hpl
Simple GUI programming with Python – p. 31/62
Creating the GUI as a class (3)
°
c www.simula.no/˜hpl
Simple GUI programming with Python – p. 32/62
Creating the GUI as a class (4)
°
c www.simula.no/˜hpl
Simple GUI programming with Python – p. 33/62
More on event bindings (1)
°
c www.simula.no/˜hpl
Simple GUI programming with Python – p. 34/62
More on event bindings (1)
Here is a unified quit function that can be used with buttons and
event bindings:
def quit(self, event=None):
self.parent.quit()
°
c www.simula.no/˜hpl
Simple GUI programming with Python – p. 35/62
A kind of calculator
°
c www.simula.no/˜hpl
Simple GUI programming with Python – p. 36/62
Turn strings into code: eval and exec
°
c www.simula.no/˜hpl
Simple GUI programming with Python – p. 37/62
A GUI for simviz1.py
°
c www.simula.no/˜hpl
Simple GUI programming with Python – p. 38/62
Layout
°
c www.simula.no/˜hpl
Simple GUI programming with Python – p. 39/62
The code (1)
class SimVizGUI:
def __init__(self, parent):
"""build the GUI"""
self.parent = parent
...
self.p = {} # holds all Tkinter variables
self.p[’m’] = DoubleVar(); self.p[’m’].set(1.0)
self.slider(slider_frame, self.p[’m’], 0, 5, ’m’)
self.p[’b’] = DoubleVar(); self.p[’b’].set(0.7)
self.slider(slider_frame, self.p[’b’], 0, 2, ’b’)
self.p[’c’] = DoubleVar(); self.p[’c’].set(5.0)
self.slider(slider_frame, self.p[’c’], 0, 20, ’c’)
°
c www.simula.no/˜hpl
Simple GUI programming with Python – p. 40/62
The code (2)
°
c www.simula.no/˜hpl
Simple GUI programming with Python – p. 41/62
The text entry field
°
c www.simula.no/˜hpl
Simple GUI programming with Python – p. 42/62
The result is not good...
Ugly!
°
c www.simula.no/˜hpl
Simple GUI programming with Python – p. 43/62
Improved text entry layout
Use the grid geometry manager to place labels and text entry fields
in a spreadsheet-like fashion:
def textentry(self, parent, variable, label):
"""make a textentry field tied to variable"""
l = Label(parent, text=label)
l.grid(column=0, row=self.row_counter, sticky=’w’)
widget = Entry(parent, textvariable=variable, width=8)
widget.grid(column=1, row=self.row_counter)
self.row_counter += 1
return widget
You can mix the use of grid and pack, but not within the same frame
°
c www.simula.no/˜hpl
Simple GUI programming with Python – p. 44/62
The image
sketch_frame = Frame(self.parent)
sketch_frame.pack(side=’left’, padx=2, pady=2)
gifpic = os.path.join(os.environ[’scripting’],
’src’,’gui’,’figs’,’simviz2.xfig.t.gif’)
self.sketch = PhotoImage(file=gifpic)
# (images must be tied to a global or class variable!)
Label(sketch_frame,image=self.sketch).pack(side=’top’,pady=20)
°
c www.simula.no/˜hpl
Simple GUI programming with Python – p. 45/62
Simulate and visualize buttons
°
c www.simula.no/˜hpl
Simple GUI programming with Python – p. 46/62
Resizing widgets (1)
Problem: the text widget is not resized when the main window is
resized
°
c www.simula.no/˜hpl
Simple GUI programming with Python – p. 47/62
Resizing widgets (2)
°
c www.simula.no/˜hpl
Simple GUI programming with Python – p. 48/62
Test/doc part of library files
°
c www.simula.no/˜hpl
Simple GUI programming with Python – p. 49/62
Customizing fonts and colors
°
c www.simula.no/˜hpl
Simple GUI programming with Python – p. 50/62
Setting widget options in a file
°
c www.simula.no/˜hpl
Simple GUI programming with Python – p. 51/62
Setting widget options in a script
°
c www.simula.no/˜hpl
Simple GUI programming with Python – p. 52/62
Key bindings in a text widget
°
c www.simula.no/˜hpl
Simple GUI programming with Python – p. 53/62
Tags
°
c www.simula.no/˜hpl
Simple GUI programming with Python – p. 54/62
Problems with function calls with args
We want to call
self.hwtext.tag_configure(’tag1’, background=’blue’)
when the mouse is over the text marked with tag1
The statement
self.hwtext.tag_bind(’tag1’,’<Enter>’,
self.tag_configure(’tag1’, background=’blue’))
does not work, because function calls with arguments are not
allowed as parameters to a function (only the name of the function,
i.e., the function object, is allowed)
Remedy: lambda functions
°
c www.simula.no/˜hpl
Simple GUI programming with Python – p. 55/62
Lambda functions in Python
General rule:
lambda arg1, arg2, ... : expression with arg1, arg2, ...
is equivalent to
def (arg1, arg2, ...):
return expression with arg1, arg2, ...
°
c www.simula.no/˜hpl
Simple GUI programming with Python – p. 56/62
Example on lambda functions
°
c www.simula.no/˜hpl
Simple GUI programming with Python – p. 57/62
Lambda functions in the event binding
°
c www.simula.no/˜hpl
Simple GUI programming with Python – p. 58/62
Lambda function dissection
Why?
The function is called as some anonymous function
def func(event=None):
and we want the body to call self.hwtext, but self does not
have the right class instance meaning in this function
Remedy: keyword argument x holding the right reference to the
function we want to call
°
c www.simula.no/˜hpl
Simple GUI programming with Python – p. 59/62
Generating code at run time (1)
°
c www.simula.no/˜hpl
Simple GUI programming with Python – p. 60/62
Generating code at run time (2)
°
c www.simula.no/˜hpl
Simple GUI programming with Python – p. 61/62
Designer tools/GUI builders
With the basic knowledge of GUI programming, you may try out a
designer tool for interactive automatic generation of a GUI
Several alternatives exist:
Tkinter: Rapyd-Tk, Visual Tkinter, Komodo, PAGE
PyGtk: Glade, see doc.html for introductions
Working style: pick a widget, place it in the GUI window, open a
properties dialog, set packing parameters, set callbacks etc.
°
c www.simula.no/˜hpl
Simple GUI programming with Python – p. 62/62