Chapter 11 – Graphical User Interface
Components: Part 2
Outline
11.1
11.2
11.3
11.4
11.5
11.6
11.7
11.8
11.9
Introduction
Overview of Pmw
ScrolledListbox Component
ScrolledText Component
MenuBar Component
Popup Menus
Canvas Component
Scale Component
Other GUI Toolkits
 2002 Prentice Hall. All rights reserved.
1
2
11.1 Introduction
• More advanced components and more complex
GUIs
• Python megawidgets (Pmw) toolkit provides highlevel GUI components developed from smaller
Tkinter components
• Introduce more Tkinter classes
 2002 Prentice Hall. All rights reserved.
3
11.2 Overview of Pmw
• Each Pmw component combines Tkinter
components to create a useful, more complex
component
• Each subcomponent can be configured
independently
• Pmw option names have the form
subcomponent_option
• Method configure alters Pmw options
 2002 Prentice Hall. All rights reserved.
4
11.3 ScrolledListbox Component
• List box
– Sometimes called a drop-down list
– Provides a list of items from which a user can select
– Implemented by Tkinter class Listbox
– Scrolling through a list can be accomplished with a
Tkinter Scrollbar
• Pmw ScrolledListbox megawidget
combines Tkinter classes Listbox and
Scrollbar
 2002 Prentice Hall. All rights reserved.
5
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# Fig. 11.1: fig11_01.py
# ScrolledListBox used to select image.
Import Pmw
from Tkinter import
*
import Pmw
module
Outline
fig11_01.py
class ImageSelection( Frame ):
"""List of available images and an area to display them"""
def __init__( self, images ):
"""Create list of PhotoImages and Label to display them"""
Initialize Pmw
Frame.__init__( self )
Pmw.initialise()
self.pack( expand = YES, fill = BOTH )
self.master.title( "Select an image" )
self.photos = []
# add PhotoImage objects to list photos
for item in images:
self.photos.append( PhotoImage( file = item ) )
Create ScrolledListBox Assign
component
list to option items
# create scrolled list
boxnumber
with vertical
scrollbar
Default
of list items
to display
Scrollbar
self.listBox = Pmw.ScrolledListBox( self, items = always
images,present
for list
selection event
listbox_height = Set
3, callback
vscrollmode
= "static",
selectioncommand = self.switchImage )
self.listBox.pack( side = LEFT, expand = YES, fill = BOTH,
padx = 5, pady = 5 )
self.display = Label( self, image = self.photos[ 0 ] )
self.display.pack( padx = 5, pady = 5 )
def switchImage( self ):
"""Change image in Label to current selection"""
 2002 Prentice Hall.
All rights reserved.
6
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
Return tuple containing index of selectedOutline
item
# get tuple containing index of selected list item
chosenPicture = self.listBox.curselection()
# configure label to display selected image
if chosenPicture:
choice = int( chosenPicture[ 0 ] )
self.display.config( image = self.photos[ choice ] )
fig11_01.py
def main():
images = [ "bug1.gif", "bug2.gif",
"travelbug.gif", "buganim.gif" ]
ImageSelection( images ).mainloop()
if __name__ == "__main__":
main()
 2002 Prentice Hall.
All rights reserved.
7
11.4 ScrolledText Component
• Pmw ScrolledText component combines
Tkinter Text and Scrollbar components
• Sometimes an external event (i.e., an event
generated by a different GUI component) indicates
when to process the text in a ScrolledText
component
 2002 Prentice Hall. All rights reserved.
8
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
Outline
# Fig. 11.2: fig11_02.py
# Copying selected text from one text area to another.
from Tkinter import *
import Pmw
fig11_02.py
class CopyTextWindow( Frame ):
"""Demonstrate ScrolledTexts"""
def __init__( self ):
"""Create two ScrolledTexts and a Button"""
Frame.__init__( self )
Pmw.initialise()
self.pack( expand = YES, fill = BOTH )
self.master.title( "ScrolledText Demo" )
Create Pmw ScrolledText component
# create scrolled text box with word wrap enabled
Enable word wrap
Set number of columns
Set number
of rows
self.text1 = Pmw.ScrolledText(
self,
Vertical
scrollbar always present
text_width =Horizontal
25, text_height
12, text_wrap
scrollbar=always
present = WORD,
hscrollmode = "static", vscrollmode = "static" )
self.text1.pack( side = LEFT, expand = YES, fill = BOTH,
padx = 5, pady = 5 )
self.copyButton = Button( self, text = "Copy >>>",
command = self.copyText )
self.copyButton.pack( side = LEFT, padx = 5, pady = 5 )
Create uneditable ScrolledText component
# create uneditable scrolled text box
self.text2 = Pmw.ScrolledText( self, text_state = DISABLED,
text_width = 25, text_height = 12, text_wrap = WORD,
hscrollmode = "static", vscrollmode = "static" )
self.text2.pack( side = LEFT, expand = YES, fill = BOTH,
padx = 5, pady = 5 )
 2002 Prentice Hall.
All rights reserved.
9
36
37
38
39
40
41
42
43
44
45
def copyText( self ):
Retrieve text
"""Set the text in the second ScrolledText"""
Outlinetext1
from ScrolledText component
self.text2.settext( self.text1.get( SEL_FIRST, SEL_LAST ) )
def
fig11_02.py
Arguments specify range
of text
to retrieve
main():
Display
text1’s
selected text in ScrolledText component text2
CopyTextWindow().mainloop()
if __name__ == "__main__":
main()
 2002 Prentice Hall.
All rights reserved.
10
11.5 MenuBar Component
• Menus
– Contain lists of actions
– Simply the appearance of GUIs
• Pmw MenuBar contains methods necessary to
manage a menu bar, a container for menus
• Menu item – GUI component inside a menu that
performs an action when selected by a user
– command menu item – initiates an action
– checkbutton menu item – toggled on or off
– radiobutton menu item – a group presents mutually
exclusive options
 2002 Prentice Hall. All rights reserved.
11
11.5 Menubar Component
– separator menu item – horizontal line groups related
menu items
– cascade menu item – submenu (or cascade menu)
provides more menu items from which users can select
• Balloons (also called tool-tips) display
descriptions of menus and menu items
 2002 Prentice Hall. All rights reserved.
12
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
Outline
# Fig. 11.3: fig11_03.py
# MenuBars with Balloons demonstration.
from Tkinter import *
import Pmw
import sys
fig11_03.py
class MenuBarDemo( Frame ):
"""Create window with a MenuBar"""
def __init__( self ):
"""Create a MenuBar with items and a Canvas with text"""
Frame.__init__( self )
Pmw.initialise()
self.pack( expand = YES, fill = BOTH )
self.master.title( "MenuBar Demo" )
Create
a Pmw
self.master.geometry( "500x200"
)
Balloon component
Create Pmw MenuBar component
self.myBalloon
= Pmw.Balloon(
self )
Specify
Balloon component
attached to MenuBar
self.choices = Pmw.MenuBar( self,
balloon = self.myBalloon )
self.choices.pack( fill = X )
Second argument specifies text of balloon
Additems
menu
File to Pmw
choices
# create File menu and Add
command
menuMenuBar
item to File
menu
Associate
menu
item
with
event
Set
name
handler
of
menu
item
self.choices.addmenu( "File", "Exit" )
self.choices.addmenuitem( "File", "command",
command = self.closeDemo, label = "Exit" )
Add submenu Color to menu Format
# create Format menu and items
Add separator menu item to menu Format
self.choices.addmenu( "Format", "Change font/color" )
self.choices.addcascademenu( "Format", "Color" )
self.choices.addmenuitem( "Format", "separator" )
self.choices.addcascademenu( "Format", "Font" )
 2002 Prentice Hall.
All rights reserved.
13
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# add items to Format/Color menu
colors = [ "Black", "Blue", "Red", "Green" ]
self.selectedColor = StringVar()
self.selectedColor.set( colors[ 0 ] )
Outline
Create radiobutton
menu items
fig11_03.py
Associate grouped radiobutton menu items
with same callback
for item in colors:
self.choices.addmenuitem(
"Color",
"radiobutton",
Associate grouped
radiobutton
menu items
label = item, command = self.changeColor,
variable = self.selectedColor )
with same variable
# add items to Format/Font menu
fonts = [ "Times", "Courier", "Helvetica" ]
self.selectedFont = StringVar()
self.selectedFont.set( fonts [ 0 ] )
for item in fonts:
self.choices.addmenuitem( "Font", "radiobutton",
label = item, command = self.changeFont,
variable = self.selectedFont )
# add a horizontal separator in Font menu
self.choices.addmenuitem( "Font", "separator" )
Create checkbutton menu item
# associate checkbutton menu item with BooleanVar object
self.boldOn = BooleanVar()
self.choices.addmenuitem( "Font", "checkbutton",
label = "Bold", command = self.changeFont,
variable = self.boldOn )
# associate checkbutton menu item with BooleanVar object
self.italicOn = BooleanVar()
self.choices.addmenuitem( "Font", "checkbutton",
label = "Italic", command = self.changeFont,
variable = self.italicOn )
 2002 Prentice Hall.
All rights reserved.
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
Create a Tkinter Canvas component with a white background
text
Outline
# create Canvas with
self.display = Canvas( self, bg = "white" )
self.display.pack( expand = YES, fill = BOTH )
Display Canvas text item
fig11_03.py
self.display.create_text( 250, 100,
self.sampleText =
text = "Sample Text", font = "Times 48" )
def changeColor( self ):
Method
configures
"""Change the color of the
text itemconfig
on the Canvas"""
Canvas items
Set fill color of Canvas item
self.display.itemconfig( self.sampleText,
fill = self.selectedColor.get() )
def changeFont( self ):
"""Change the font of the text on the Canvas"""
# get selected font and attach size
newFont = self.selectedFont.get() + " 48"
# determine which checkbutton menu items selected
if self.boldOn.get():
newFont += " bold"
if self.italicOn.get():
newFont += " italic"
# configure sample text to be displayed in selected style
self.display.itemconfig( self.sampleText, font = newFont )
def closeDemo( self ):
"""Exit the
program"""
Terminate
the program
sys.exit()
 2002 Prentice Hall.
All rights reserved.
14
15
105
106
107
108
109
def main():
MenuBarDemo().mainloop()
if __name__ == "__main__":
main()
Outline
fig11_03.py
 2002 Prentice Hall.
All rights reserved.
16
11.6 Popup Menus
• Context-sensitive popup menus created with
Tkinter class Menu
• Provide options specific to the component for
which generated the popup trigger event
 2002 Prentice Hall. All rights reserved.
17
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
Outline
# Fig. 11.4: fig11_04.py
# Popup menu demonstration.
from Tkinter import *
fig11_04.py
class PopupMenuDemo( Frame ):
"""Demonstrate popup menus"""
def __init__( self ):
"""Create a Menu but do not add it to the Frame"""
Frame.__init__( self )
self.pack( expand = YES, fill = BOTH )
self.master.title( "Popup Menu Demo" )
self.master.geometry( "300x200" )
# create and pack frame with initial white background
self.frame1 = Frame( self, bg = "white" )
self.frame1.pack( expand = YES, fill = BOTH )
Create Tkinter Menu
component
Remove
default first entry, a dashed separator item
# create menu without packing it
self.menu = Menu( self.frame1, tearoff = 0 )
colors = [ "White", "Blue", "Yellow", "Red" ]
self.selectedColor = StringVar()
self.selectedColor.set( colors[ 0 ] )
Add radiobutton menu item to Tkinter Menu component
for item in colors:
self.menu.add_radiobutton( label = item,
variable = self.selectedColor,
command = self.changeBackgroundColor
Associate right-mouse click) event
# popup menu on right-mouse click
self.frame1.bind( "<Button-3>", self.popUpMenu )
with callback popupMenu
 2002 Prentice Hall.
All rights reserved.
18
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
def popUpMenu( self, event ):
"""Add the Menu to the Frame"""
Outline
Display Menu component at given coordinates
self.menu.post( event.x_root, event.y_root )
fig11_04.py
def changeBackgroundColor( self ):
"""Change the Frame background color"""
Set Frame component’s background color
self.frame1.config( bg = self.selectedColor.get() )
def main():
PopupMenuDemo().mainloop()
if __name__ == "__main__":
main()
 2002 Prentice Hall.
All rights reserved.
19
11.7 Canvas Component
• Tkinter component Canvas displays text,
images, lines and shapes
• Blank by default
• Program creates canvas items to display items on a
Canvas
• New items drawn on existing items unless
otherwise specified
 2002 Prentice Hall. All rights reserved.
20
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
Outline
# Fig. 11.5: fig11_05.py
# Canvas paint program.
from Tkinter import *
fig11_05.py
class PaintBox( Frame ):
"""Demonstrate drawing on a Canvas"""
def __init__( self ):
"""Create Canvas and bind paint method to mouse dragging"""
Frame.__init__( self )
self.pack( expand = YES, fill = BOTH )
self.master.title( "A simple paint program" )
self.master.geometry( "300x150" )
self.message = Label( self,
text = "Drag the mouse to draw" )
self.message.pack( side = BOTTOM )
Create Tkinter Canvas component
# create Canvas component
self.myCanvas = Canvas( self )
self.myCanvas.pack( expand
= YES,
fill =event
BOTH to
)
Bind mouse
dragging
Canvas component
# bind mouse dragging event to Canvas
self.myCanvas.bind( "<B1-Motion>", self.paint )
def paint( self, event ):
"""Create an oval of
radiusx-4 and
around
the mouse of
position"""
Retrieve
y- coordinates
mouse position
Create
oval Canvas
x1, y1 = ( event.x - 4 ),
( event.y
- 4 ) item
x2, y2 = ( event.x + 4 ), ( event.y + 4 )
self.myCanvas.create_oval( x1, y1, x2, y2, fill = "black" )
 2002 Prentice Hall.
All rights reserved.
21
35
36
37
38
39
def main():
PaintBox().mainloop()
if __name__ == "__main__":
main()
Outline
fig11_05.py
 2002 Prentice Hall.
All rights reserved.
22
11.8 Scale Component
• Tkinter component Scale enables user to
select from a range of integer values
• Has numeric values and a slider
• Horizontal orientation: minimum value at extreme
left and maximum value at extreme right
• Vertical orientation: minimum value at extreme
top and maximum value at extreme bottom
 2002 Prentice Hall. All rights reserved.
23
11.8 Scale Component
Numeric value
slider
 2002 Prentice Hall. All rights reserved.
24
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# Fig. 11.7: fig11_07.py
# Scale used to control the size of a circle.
from Tkinter import *
Outline
fig11_07.py
class ScaleDemo( Frame ):
"""Demonstrate Canvas and Scale"""
def __init__( self ):
"""Create Canvas with a circle controlled by a Scale"""
Frame.__init__( self )
self.pack( expand = YES, fill = BOTH )
self.master.title( "Scale Demo" )
self.master.geometry( "220x270" )
Specify
Scale’s
maximum value
Create Tkinter
Specify
Scale
Scale’s
component
minimum
value
# create Scale
self.control = Scale( self, from_ = 0, to = 200,
Set initial
Scale
value
orient = HORIZONTAL,
command
= self.updateCircle
)
self.control.pack( side = BOTTOM, fill = X )
self.control.set( 10 )
# create Canvas and draw circle
self.display = Canvas( self, bg = "white" )
self.display.pack( expand = YES, fill = BOTH )
def updateCircle( self, scaleValue ):
"""Delete the circle, determine new size, draw again"""
Delete previously drawn Canvas item
end = int( scaleValue )
+ 10 oval Canvas item
Create
self.display.delete( "circle"
)
Option tags
sets Canvas item’s name
self.display.create_oval( 10, 10, end, end,
fill = "red", tags = "circle" )
def main():
 2002 Prentice Hall.
All rights reserved.
25
36
37
38
39
ScaleDemo().mainloop()
if __name__ == "__main__":
main()
Outline
fig11_07.py
 2002 Prentice Hall.
All rights reserved.
26
11.9 Other GUI Toolkits
• PyGTK provides object-oriented interface for the
Gimp Toolkit component set
• wxPython extension module enables access to
wxWindows, a GUI C++ library
• PyOpenGL interface to OpenGL
 2002 Prentice Hall. All rights reserved.