Chapter 4 – Control Structures Part 1

Chapter 10 – Graphical User Interface
Components: Part 1
Outline
10.1
10.2
10.3
10.4
10.5
10.6
10.7
10.8
10.9
10.10
10.11
10.12
Introduction
Tkinter Overview
Simple Tkinter Example: Label Component
Event Handling Model
Entry Component
Button Component
Checkbutton and Radiobutton Components
Mouse Event Handling
Keyboard Event Handling
Layout Managers
10.10.1 Pack
10.10.2 Grid
10.10.3 Place
Card Shuffling and Dealing Simulation
Internet and World Wide Web Resources
 2002 Prentice Hall. All rights reserved.
1
2
10.1 Introduction
• Graphical user interface (GUI) enables user
interaction via mouse or keyboard with program
• GUIs built from components called widgets
 2002 Prentice Hall. All rights reserved.
3
10.1 Introduction
Menu bar
Button
Fig. 10.1
 2002 Prentice Hall. All rights reserved.
Label
Menu
Text field
GUI components in an Internet Explorer window.
4
10.1 Introduction
C omp o ne nt
De sc rip tio n
Frame
Serves as a container for other components.
Label
Entry
Displays uneditable text or icons.
Text
Accepts user input from the keyboard, or displays information. A
multiple-line input area.
Accepts user input from the keyboard, or displays information. A
single-line input area.
Triggers an event when clicked.
Button
Selection component that is either chosen or not chosen.
Checkbutton
Selection component that allows the user to choose only one option.
Radiobutton
Displays a list of items from which the user can select.
Menu
Displays text, images, lines or shapes.
Canvas
Allows the user to select from a range of integers using a slider.
Scale
Displays a list of text options.
Listbox
Displays popup or pull-down menu.
Menubutton
Displays a scrollbar for canvases, text fields and lists.
Scrollbar
Fig. 10.2 GUI c om p onents.
 2002 Prentice Hall. All rights reserved.
5
10.2 Tkinter Overview
• Python’s standard GUI package – Tkinter
module
• Tkinter library provides object-oriented
interface to Tk GUI toolkit
• Each GUI component class inherits from class
Widget
• GUI consists of top-level (or parent) component
that can contain children components
• Class Frame serves as a top-level component
 2002 Prentice Hall. All rights reserved.
6
10.2 Tkinter Overview
Frame
Widget
Label
Entry
Text
Button
Checkbutton
Radiobutton
Menu
Canvas
Scale
Listbox
Key
Subclass name
Class name
Fig. 10.3
 2002 Prentice Hall. All rights reserved.
Widget subclasses.
Scrollbar
Menubutton
10.3 Simple Tkinter Example: Label
Component
• Labels
– Display text or images
– Provide instructions and other information
– Created by Tkinter class Label
 2002 Prentice Hall. All rights reserved.
7
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
# Fig. 10.4: fig10_04.py
# Label demonstration.
Allows program
from Tkinter importParent
*
Outline
to access definitions without the module name
container inherits from Frame
fig10_04.py
class LabelDemo( Frame ):
"""Demonstrate Labels"""
def __init__( self ):
"""Create three Labels and pack them"""
Base-class constructor initializes top-level component
Frame.__init__(
self and
) #
Frame object
Method pack
itsinitializes
keyword arguments
specifies how and where to place components
Attribute
master
references
component’s parent
# frame fills
all available
Sets
title ofspace
GUI
self.pack( expand = YES, fill = BOTH )
self.master.title( "Labels"
)
Create Label
component
to display specified text
self.Label1 = Label( self, text = "Label with text" )
Place
Label1 Label
with method
# resize frame to
accommodate
self.Label1.pack()
pack’s default settings
self.Label2 = Label( self,
text = "Labels with text and a bitmap" )
Places Label2 against frame’s left side
# insert Label against left side of frame
self.Label2.pack( side = LEFT )
# using default bitmap image as label Display warning
self.Label3 = Label( self, bitmap = "warning" )
self.Label3.pack( side = LEFT )
def main():
Start GUI program
LabelDemo().mainloop() # starts event loop
bitmap image on label
 2002 Prentice Hall.
All rights reserved.
9
36
37
if __name__ == "__main__":
main()
Outline
fig10_04.py
 2002 Prentice Hall.
All rights reserved.
10.3 Simple Tkinter Example: Label
Component
Bitm a p im a g e na m e
Im a g e
Bitm a p im a g e na m e
error
hourglass
gray75
info
gray50
questhead
gray25
question
gray12
warning
Fig. 10.5
Bitm a p im a g es a va ila b le.
 2002 Prentice Hall. All rights reserved.
Im a g e
10
11
10.4 Event Handling Model
• GUI components generate events due to user
interaction
• Asynchronous event-driven programs
• Programs bind event to graphical component and
implement event handler (or callback) to process
GUI event
 2002 Prentice Hall. All rights reserved.
12
10.5 Entry Component
• Text fields
– Areas in which users can enter text or programmers can
display a line of text
– Created by Entry class
• <Return> event occurs when user presses Enter
key inside Entry component
 2002 Prentice Hall. All rights reserved.
13
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. 10.6: fig10_06.py
# Entry components and event binding demonstration.
from Tkinter importContains
*
from tkMessageBox import *
functions that display dialogs
Outline
fig10_06.py
class EntryDemo( Frame ):
"""Demonstrate Entrys and Event binding"""
def __init__( self ):
"""Create, pack and bind events to four Entrys"""
Frame.__init__( self )
self.pack( expand = YES, fill = BOTH )
Configures
length and width
of top-level component in pixels
self.master.title( "Testing
Entry Components"
)
self.master.geometry(Create
"325x100"
) component
# width x as
length
Frame
container for two Entry components
of vertical space between frame1 and other components
Create Entry component and set its name
Specifies
5 pixels
self.frame1 = Frame(
self
)
self.frame1.pack( pady = 5 )
self.text1 = Entry( self.frame1, name = "text1" )
Associate Entry component text1 with Enter key event
Specify event handler as second argument
Entry
component
to event
Specifies
5 pixels
of horizontal space between text1 and other components
# bind the
self.text1.bind( "<Return>", self.showContents )
self.text1.pack( side = LEFT, padx = 5 )
self.text2 = Entry( self.frame1, name = "text2" )
Display text in Entry component
# insert text into Entry component text2
self.text2.insert( INSERT, "Enter text here" )
self.text2.bind( "<Return>", self.showContents )
self.text2.pack( side = LEFT, padx = 5 )
Create frame2 as container for next 2 Entry components
self.frame2 = Frame( self )
self.frame2.pack( pady = 5 )
 2002 Prentice Hall.
All rights reserved.
14
Outline
36
37
self.text3 = Entry( self.frame2, name = "text3" )
38
self.text3.insert( INSERT, "Uneditable text field" )
39
fig10_06.py
Method
config
Entrycomponent
component
text3’s state
to DISABLED
40
# prohibit user from
altering
text sets
in Entry
text3
41
self.text3.config( state = DISABLED )
42
self.text3.bind( "<Return>", self.showContents )
43
self.text3.pack( side = LEFT, padx = 5 )
44
45
# text in Entry component text4 appears as *
Display
asterisks rather
text in Entry component text4
46
self.text4 = Entry(
self.frame2,
name than
= "text4",
47
show = "*" )
48
self.text4.insert( INSERT, "Hidden text" )
49
self.text4.bind( "<Return>", self.showContents )
50
self.text4.pack( side = LEFT, padx = 5 )
Event handler displays Entry component’s name and entered text
51
52
def showContents( self, event ):
53
"""Display the contents of the Entry"""
54
Returns name of component associated with event
55
# acquire name of Entry component that generated event
56
theName = event.widget.winfo_name()
57
contents
componentevent
58
# acquire Display
contents
of Entry
component
thatofgenerated
dialog
boxReturns
59
theContents = event.widget.get()
60
showinfo( "Message", theName + ": " + theContents )
61
Invoke GUI’s event loop
62 def main():
63
EntryDemo().mainloop()
64
65 if name__ == "__main__":
66
main()
 2002 Prentice Hall.
All rights reserved.
15
Outline
fig10_06.py
 2002 Prentice Hall.
All rights reserved.
16
10.6 Button components
• Buttons
– Generates events when selected
– Facilitate selection of actions
– Created with class Button
– Displays text or image called button label
– Each should have unique label
 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
Outline
# Fig. 10.7: fig10_07.py
# Button demonstration.
from Tkinter import *
from tkMessageBox import *
fig10_07.py
class PlainAndFancy( Frame ):
"""Create one plain and one fancy button"""
def __init__( self ):
"""Create two buttons, pack them and bind events"""
Frame.__init__( self )
self.pack( expand = YES, fill = BOTH )
self.master.title( "Buttons" )
Create Button component displaying specified text label
# create button with text
self.plainButton
= Button(
self,
"Plain Button",
Associate
button
withtext
event=handler
cursor rolling over button associated with callback
command = self.pressedPlainMouse
)
self.plainButton.bind( "<Enter>", self.rolloverEnter
)
Mouse leaving button
associated with callback
self.plainButton.bind( "<Leave>", self.rolloverLeave )
self.plainButton.pack( side = LEFT, padx = 5, pady = 5 )
Button components display PhotoImage objects
indicated by image option
# create button with image
Button displays
object
self.myImage = PhotoImage( file = "logotiny.gif"
)
self.fancyButton = Button( self, image = self.myImage,
command = self.pressedFancy )
self.fancyButton.bind( "<Enter>", self.rolloverEnter )
self.fancyButton.bind( "<Leave>", self.rolloverLeave )
self.fancyButton.pack( side = LEFT, padx = 5, pady = 5 )
def pressedPlain( self ):
showinfo( "Message", "You pressed: Plain Button" )
 2002 Prentice Hall.
All rights reserved.
18
35
36
37
38
39
40
41
42
43
44
45
46
47
48
def pressedFancy( self ):
showinfo( "Message", "You pressed: Fancy Button" )
Outline
Changes
of button
mouse
cursor rolls
over components
it
Button’sappearance
relief
specifies
how when
it appears
to other
Sets
Button
component’s
reliefintorelation
GROOVE
def rolloverEnter( self, event ):
fig10_07.py
event.widget.config( relief = GROOVE )
Changes appearance of button when mouse cursor leaves it
Sets Button component’s relief to RAISED
def rolloverLeave( self, event ):
event.widget.config( relief = RAISED )
def main():
PlainAndFancy().mainloop()
if __name__ == "__main__":
main()
 2002 Prentice Hall.
All rights reserved.
10.7 Checkbutton and Radiobutton
Components
• Checkbox
–
–
–
–
–
Small white square
Either blank or contains a checkmark
Descriptive text referred to as checkbox label
Any number of boxes selected at a time
Created by class Checkbutton
• Radio button
– Mutually excusive options – only one radio button selected
at a time
– Created by class Radiobutton
• Both have on/off or true/false values and two
states – selected and not selected (deselected)
 2002 Prentice Hall. All rights reserved.
19
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. 10.8: fig10_08.py
# Checkbuttons demonstration.
from Tkinter import *
fig10_08.py
class CheckFont( Frame ):
"""An area of text with Checkbutton controlled font"""
def __init__( self ):
"""Create an Entry and two Checkbuttons"""
Frame.__init__( self )
self.pack( expand = YES, fill = BOTH )
self.master.title( "Checkbutton Demo" )
self.frame1 = Frame( self )
self.frame1.pack()
Attribute font specifies style of text in Entry component
self.text = Entry( self.frame1, width = 40,
font = "Arial 10" )
self.text.insert( INSERT, "Watch the font style change" )
self.text.pack( padx = 5, pady = 5 )
self.frame2 = Frame( self )
self.frame2.pack()
Subclass of Tkinter class Variable
Container object for integer with value 0 (false) or 1 (true)
# create boolean variable
self.boldOn = BooleanVar()
Create Checkbutton with label specified by text value
# create "Bold"
checkbutton
variable
requires an
object of
Tkinter
or itscheckBold
subclasses
BooleanVar
boldOn
stores
state ofVariable
Checkbutton
Binds
selection
of
Checkbutton
to callback
self.checkBold = Checkbutton( self.frame2, text = "Bold",
variable = self.boldOn, command = self.changeFont )
self.checkBold.pack( side = LEFT, padx = 5, pady = 5 )
 2002 Prentice Hall.
All rights reserved.
21
35
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
# create boolean variable
Create
self.italicOn = BooleanVar()
Outline
another BooleanVar object for the second Checkbutton
# create "Italic" checkbutton
self.checkItalic = Checkbutton( self.frame2,
text = "Italic", variable = self.italicOn,
command = self.changeFont )
self.checkItalic.pack( side = LEFT, padx = 5, pady = 5 )
fig10_08.py
def changeFont( self ):
"""Change the font based on selected Checkbuttons"""
desiredFont = "Arial Returns
10"
value of specified Variable object
if self.boldOn.get():
desiredFont += " bold"
if self.italicOn.get():
desiredFont += Set
" italic"
font of Entry
component text to style specified by checkbox states
self.text.config( font = desiredFont )
def main():
CheckFont().mainloop()
if __name__ == "__main__":
main()
 2002 Prentice Hall.
All rights reserved.
22
Outline
fig10_08.py
 2002 Prentice Hall.
All rights reserved.
23
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
Outline
# Fig. 10.9: fig10_09.py
# Radiobuttons demonstration.
from Tkinter import *
fig10_09.py
class RadioFont( Frame ):
"""An area of text with Radiobutton controlled font"""
def __init__( self ):
"""Create an Entry and four Radiobuttons"""
Frame.__init__( self )
self.pack( expand = YES, fill = BOTH )
self.master.title( "Radiobutton Demo" )
self.frame1 = Frame( self )
self.frame1.pack()
self.text = Entry( self.frame1, width = 40,
font = "Arial 10" )
self.text.insert( INSERT, "Watch the font style change" )
self.text.pack( padx = 5, pady = 5 )
self.frame2 = Frame( self )
self.frame2.pack()
fontSelections = [ "Plain", "Bold", "Italic",
Subclass of Variable that
"Bold/Italic" ]
self.chosenFont = StringVar()
stores strings
# initial selection
A group of Radiobuttons
self.chosenFont.set( fontSelections[ 0 ] )
modifies the same variable
Set StringVar chosenFont to default style Plain
 2002 Prentice Hall.
All rights reserved.
24
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
Outline
# create group of Radiobutton components with same variable
Create Radiobutton
with
specified
by text
for style in fontSelections:
Each Radiobutton
in a group
haslabel
same
variable
valuevalue
aButton = Radiobutton( self.frame2, text = style,
variable = self.chosenFont, value = style,
fig10_09.py
command = self.changeFont )
specifies Radiobutton’s
aButton.pack( side = LEFT, padx = 5, Option
pady = value
5 )
name
def changeFont( self ):
"""Change the font based on selected Radiobutton"""
desiredFont = "Arial 10"
Returns value of specified Variable object
if self.chosenFont.get() == "Bold":
desiredFont += " bold"
elif self.chosenFont.get() == "Italic":
desiredFont += " italic"
elif self.chosenFont.get() == "Bold/Italic":
desiredFont += " bold italic"
self.text.config( font = desiredFont )
def main():
RadioFont().mainloop()
if __name__ == "__main__":
main()
 2002 Prentice Hall.
All rights reserved.
25
Outline
fig10_09.py
 2002 Prentice Hall.
All rights reserved.
26
10.8 Mouse Event Handling
• Events that occur as a result of user interaction
with a mouse
• Tkinter events described by strings following
pattern <modifier-type-detail>
– type specifies kind of event (e.g. Button and Return)
– Specific mouse button is example of a detail
– Prefix Double is example of a modifier
 2002 Prentice Hall. All rights reserved.
27
10.8 Mouse Event Handling
Event forma t
De sc rip tio n
<ButtonPress-n>
Mouse button n has been selected while the mouse pointer is
over the component. n may be 1 (left button), 2 (middle button)
or 3 (right button). (e.g., <ButtonPress-1>).
<Button-n>, <n>
<ButtonReleasen>
<Bn-Motion>
<Prefix-Button-n>
Shorthand notations for <ButtonPress-n>.
Mouse button n has been released.
<Enter>
<Leave>
Fig. 10.10
Mouse pointer has entered the component.
Mouse is moved with button n held down.
Mouse button n has been Prefix clicked over the component.
Prefix may be Double or Triple.
Mouse pointer has exited the component.
Mouse event form a ts.
 2002 Prentice Hall. All rights reserved.
28
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. 10.11: fig10_11.py
# Mouse events example.
from Tkinter import *
fig10_11.py
class MouseLocation( Frame ):
"""Demonstrate binding mouse events"""
def __init__( self ):
"""Create a Label, pack it and bind mouse events"""
Frame.__init__( self )
self.pack( expand = YES, fill = BOTH )
self.master.title( "Demonstrating Mouse Events" )
self.master.geometry( "275x100" )
self.mousePosition = StringVar() # displays mouse position
Text displayed
in outside
component
associated
with StringVar
self.mousePosition.set(
"Mouse
window"
)
self.positionLabel = Label( self,
textvariable = self.mousePosition )
self.positionLabel.pack( side = BOTTOM )
object
Associate clicking first mouse button with callback buttonPressed
# bind mouse events
to releasing
window first mouse button with callback buttonReleased
Associate
self.bind( Associate
"<Button-1>",
)
mouseself.buttonPressed
cursor entering window
with callback enteredWindow
self.bind( "<ButtonRelease-1>", self.buttonReleased )
Associate mouse cursor leaving window with callback exitedWindow
self.bind( Associate
"<Enter>",
self.enteredWindow
holding
first button and )dragging mouse with mouseDragged
self.bind( "<Leave>", self.exitedWindow )
self.bind( "<B1-Motion>", self.mouseDragged )
def buttonPressed( self, event ):
"""Display
press"""
Convertcoordinates
x-coordinateofofbutton
mouse click
to string
self.mousePosition.set( "Pressed at [ " + str( event.x ) +
", " + str( event.y ) + " ]" )
 2002 Prentice Hall.
All rights reserved.
29
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
def buttonReleased( self, event ):
"""Display coordinates of button release"""
self.mousePosition.set( "Released at [ " + str( event.x ) +
", " + str( event.y ) + " ]" )
Changes the text displayed by the Label
Outline
fig10_11.py
def enteredWindow( self, event ):
"""Display message that mouse has entered window"""
self.mousePosition.set( "Mouse in window" )
def exitedWindow( self, event ):
"""Display message that mouse has left window"""
self.mousePosition.set( "Mouse outside window" )
def mouseDragged( self, event ):
"""Display coordinates of mouse being moved"""
self.mousePosition.set( "Dragged at [ " + str( event.x ) +
", " + str( event.y ) + " ]" )
def main():
MouseLocation().mainloop()
if __name__ == "__main__":
main()
 2002 Prentice Hall.
All rights reserved.
30
Outline
fig10_11.py
 2002 Prentice Hall.
All rights reserved.
31
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. 10.12: fig10_12.py
# Mouse button differentiation.
from Tkinter import *
fig10_12.py
class MouseDetails( Frame ):
"""Demonstrate mouse events for different buttons"""
def __init__( self ):
"""Create a Label, pack it and bind mouse events"""
Frame.__init__( self )
self.pack( expand = YES, fill = BOTH )
self.master.title( "Mouse clicks and buttons" )
self.master.geometry( "350x150" )
# create mousePosition variable
self.mousePosition = StringVar()
positionLabel = Label( self,
textvariable = self.mousePosition )
self.mousePosition.set( "Mouse not clicked" )
positionLabel.pack( side = BOTTOM )
Associate first (left) mouse button with callback leftClick
# bind eventAssociate
handler second
to events
for each
button
(middle)
mousemouse
button
with callback centerClick
self.bind( "<Button-1>", self.leftClick )
third (right)
mouse button) with callback rightClick
self.bind( Associate
"<Button-2>",
self.centerClick
self.bind( "<Button-3>", self.rightClick )
def leftClick( self, event ):
"""Display coordinates and indicate left button clicked"""
self.showPosition( event.x, event.y )
self.master.title( "Clicked with left mouse button" )
 2002 Prentice Hall.
All rights reserved.
32
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
def centerClick( self, event ):
"""Display coordinates and indicate center button used"""
self.showPosition( event.x, event.y )
self.master.title( "Clicked with center mouse button" )
Outline
fig10_12.py
def rightClick( self, event ):
"""Display coordinates and indicate right button clicked"""
self.showPosition( event.x, event.y )
self.master.title( "Clicked with right mouse button" )
def showPosition( self, x, y ):
"""Display coordinates of button press"""
self.mousePosition.set( "Pressed at [ " + str( x ) + ", " +
str( y ) + " ]" )
def main():
MouseDetails().mainloop()
if __name__ == "__main__":
main()
 2002 Prentice Hall.
All rights reserved.
33
Outline
fig10_12.py
 2002 Prentice Hall.
All rights reserved.
34
10.9 Keyboard Event Handling
• Keyboard events generated when users press and
release keys
 2002 Prentice Hall. All rights reserved.
35
10.9 Keyboard Event Handling
Event forma t
De sc rip tio n o f Eve nt
<KeyPress>
<KeyRelease>
Any key has been selected.
Any key has been released.
<KeyPress-key>
<KeyRelease-key>
<Key>, <Key-key>
key has been selected or released.
Shorthand notation for <KeyPress>
and <KeyPress-key>.
<key>
Shorthand notation for <KeyPress-key>. This format
works only for printable characters (excluding space and lessthan sign).
key has been selected while Prefix is held down. Possible
prefixes are Alt, Shift and Control. Note that
<Prefix-key>
multiple prefixes are also possible (e.g., <Control-
Alt-key>).
Fig. 10.13
Keyb oa rd eve nt form a ts.
 2002 Prentice Hall. All rights reserved.
36
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. 10.14: fig10_14.py
# Binding keys to keyboard events.
from Tkinter import *
fig10_14.py
class KeyDemo( Frame ):
"""Demonstrate keystroke events"""
def __init__( self ):
"""Create two Labels and bind keystroke events"""
Frame.__init__( self )
self.pack( expand = YES, fill = BOTH )
self.master.title( "Demonstrating Keystroke Events" )
self.master.geometry( "350x100" )
self.message1 = StringVar()
self.line1 = Label( self, textvariable = self.message1 )
self.message1.set( "Type any key or shift" )
self.line1.pack()
self.message2 = StringVar()
self.line2 = Label( self, textvariable = self.message2 )
self.message2.set( "" )
self.line2.pack()
Pressing any key calls event handler keyPressed
handler keyReleased
# binding any key
Releasing any key calls event
self.master.bind( "<KeyPress>", self.keyPressed )
self.master.bind( "<KeyRelease>", self.keyReleased )
Pressing left shift key calls event handler shiftPressed
shiftReleased
# binding specific key
Releasing left shift
key calls event handler
self.master.bind( "<KeyPress-Shift_L>",
self.shiftPressed
)
self.master.bind( "<KeyRelease-Shift_L>",
self.shiftReleased )
 2002 Prentice Hall.
All rights reserved.
37
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
def keyPressed( self, event ):
"""Display the name of the pressed key"""
Outline
Obtain name of the key
self.message1.set( "Key pressed: " + event.char )
self.message2.set( "This key is not left shift" )
fig10_14.py
def keyReleased( self, event ):
"""Display the name of the released key"""
self.message1.set( "Key released: " + event.char )
self.message2.set( "This key is not left shift" )
def shiftPressed( self, event ):
"""Display a message that left shift was pressed"""
self.message1.set( "Shift pressed" )
self.message2.set( "This key is left shift" )
def shiftReleased( self, event ):
"""Display a message that left shift was released"""
self.message1.set( "Shift released" )
self.message2.set( "This key is left shift" )
def main():
KeyDemo().mainloop()
if __name__ == "__main__":
main()
 2002 Prentice Hall.
All rights reserved.
38
Outline
fig10_14.py
 2002 Prentice Hall.
All rights reserved.
39
10.10 Layout Managers
•
•
•
•
Arrange placement of GUI components
Provide layout capabilities
Process most of design
Tkinter offers Pack, Grid and Place classes
 2002 Prentice Hall. All rights reserved.
40
10.10 Layout Managers
La yo ut ma na g er
De sc rip tio n
Pack
Places components in the order in which they were added.
Grid
Arranges components into rows and columns.
Place
Allows the programmer to specify the size and location of components
and windows.
Fig. 10.15
GUI la yout m a na g ers.
 2002 Prentice Hall. All rights reserved.
41
10.10.1 Pack
• Pack layout manager places GUI components in
a container from top to bottom in program order,
by default
• Option side indicates side of container against
which component is placed
• Option expand determines whether the
component fills any extra space in the container
• Option fill allots amount of space the
components should occupy in the container
• Options padx and pady inserts horizontal and
vertical padding around a component, respectively
 2002 Prentice Hall. All rights reserved.
42
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. 10.16: fig10_16.py
# Pack layout manager demonstration.
from Tkinter import *
fig10_16.py
class PackDemo( Frame ):
"""Demonstrate some options of Pack"""
def __init__( self ):
"""Create four Buttons with different pack options"""
Frame.__init__( self )
self.master.title( "Packing Demo" )
self.master.geometry( "400x150" )
self.pack( expand = YES, fill = BOTH )
self.button1 = Button( self, text = "Add Button",
command = self.addButton )
Places component against top of window
# Button component placed against top of window
self.button1.pack( side = TOP )
self.button2 = Button( self,
text = "expand = NO, fill = BOTH" )
againstofbottom
of window
# Button component Places
placedcomponent
against bottom
window
# fills all available vertical and horizontal space
self.button2.pack( side = BOTTOM, fill = BOTH )
filling all available space
self.button3 = Button( self,
text = "expand = YES, fill = X" )
Places component against window’s
left space
side
any extra
Component
# Button component placed against left side
of windowfills
Component fills all available horizontal space
# fills all available horizontal space
self.button3.pack( side = LEFT, expand = YES, fill = X )
 2002 Prentice Hall.
All rights reserved.
43
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
self.button4 = Button( self,
text = "expand = YES, fill = Y" )
Component fills all available horizontal space
component
against
window’s
# Button component placed Places
against
right side
of window
# fills all available vertical space
self.button4.pack( side = RIGHT, expand = YES, fill = Y )
5
Outline
right side
fig10_16.py
def addButton( self ):
and space
pack between
a new Button"""
pixels"""Create
of horizontal
components
Button( self, text = "New Button" ).pack( pady = 5 )
def main():
PackDemo().mainloop()
if __name__ == "__main__":
main()
 2002 Prentice Hall.
All rights reserved.
44
Outline
fig10_16.py
 2002 Prentice Hall.
All rights reserved.
45
10.10.2 Grid
• Grid layout manager divides container into a grid
of rows and columns
• Components added at specified row and column
indices
• Row and column numbers begin at 0
• Option sticky specifies the component’s
alignment and whether the component stretches to
fill the cell – W, E, N, S, NW, NE, SW, SE and any
combinations concatenated with +
• Options padx and pady inserts horizontal and
vertical padding around a component, respectively
 2002 Prentice Hall. All rights reserved.
46
10.10.2 Grid
• Options ipadx and ipady inserts horizontal and
vertical padding inside a component
• Option weight indicates relative weight of
growth for a row or a column when a window is
resized
 2002 Prentice Hall. All rights reserved.
47
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. 10.17: fig10_17.py
# Grid layout manager demonstration.
from Tkinter import *
fig10_17.py
class GridDemo( Frame ):
"""Demonstrate the Grid geometry manager"""
def __init__( self ):
"""Create and grid several components into the frame"""
Frame.__init__( self )
self.master.title( "Grid Demo" )
expands
# main frame fills entire container,Top-level
expands component
if necessary
Top-level
component
entire container
self.master.rowconfigure(
0, weight
= 1 fills
)
self.master.columnconfigure( 0, weight = 1 )
self.grid( sticky = W+E+N+S )
at same rate as window
self.text1 = Text( self, width = 15, height = 5 )
Component spans 3 rows and fills available space
# text component spans three rows and all available space
self.text1.grid( rowspan = 3, sticky = W+E+N+S )
self.text1.insert( INSERT, "Text1" )
# place button component in first row, second column
Place
component
at specified
row and column
spans 2
self.button1 = Button( self,
text
= "Button
1", Component
width = 25 )
self.button1.grid( row = 0, column = 1, columnspan = 2,
sticky = W+E+N+S )
# place button component in second row, second column
self.button2 = Button( self, text = "Button 2" )
self.button2.grid( row = 1, column = 1, sticky = W+E+N+S )
columns
 2002 Prentice Hall.
All rights reserved.
48
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
# configure button component to fill all it allocated space
self.button3 = Button( self, text = "Button 3" )
self.button3.grid( row = 1, column = 2, sticky = W+E+N+S )
# span two columns starting in second column of first row
self.button4 = Button( self, text = "Button 4" )
self.button4.grid( row = 2, column = 1, columnspan = 2,
sticky = W+E+N+S )
Outline
fig10_17.py
# place text field in fourth row to span two columns
self.entry = Entry( self )
self.entry.grid( row = 3, columnspan = 2,
sticky = W+E+N+S )
self.entry.insert( INSERT, "Entry" )
# fill all available space in fourth row, third column
self.text2 = Text( self, width = 2, height = 2 )
self.text2.grid( row = 3, column = 2, sticky = W+E+N+S )
self.text2.insert( INSERT, "Text2" )
Changes row options
# make second row/column
expand
Changes
column options
self.rowconfigure( 1, weight = 1 )
self.columnconfigure( 1, weight = 1 )
def main():
GridDemo().mainloop()
if __name__ == "__main__":
main()
 2002 Prentice Hall.
All rights reserved.
49
Outline
fig10_17.py
 2002 Prentice Hall.
All rights reserved.
50
10.10.2 Grid
Grid Me thod s
De sc rip tio n
columnconfigure( column,
options )
Sets column options, such as minsize
grid()
Places a component in Grid as described by
optional keyword arguments.
Removes, but does not destroy, a component.
grid_forget()
grid_remove()
(minimum size), pad (add padding to largest
component in the column) and weight.
Removes a component, storing its associated options
in case the component is re-inserted.
grid_info()
grid_location( x, y )
Returns current options as a dictionary.
grid_size()
rowconfigure( row, options
)
Returns the grid size as a tuple ( column, row ).
Returns the grid position closest to the given pixel
coordinates as a tuple ( column, row ).
Sets row’s options, such as minsize
(minimum size), pad (add padding to largest
component in the row) and weight.
Fig. 10.18
 2002 Prentice Hall. All rights reserved.
Grid m e thod s.
51
10.10.3 Place
• Place layout manager sets the position and size
of a GUI component absolutely or relatively to the
position and size of another component
• Referenced component specified with option in_
• More complicated than other layout managers
 2002 Prentice Hall. All rights reserved.
52
10.10.3 Place
Place Me thod
De sc rip tio n
place()
Inserts a component as specified by keyword arguments.
place_forget( Removes, but does not destroy, a component.
)
place_info() Returns current options in a dictionary.
place_configu Positions a component as specified by keyword arguments.
re()
Fig. 10.19
Place m ethod s.
 2002 Prentice Hall. All rights reserved.
53
10.10.3 Place
Place Op tion
De sc rip tio n
x
Designates the absolute horizontal position of the component.
y
relx
Designates the absolute vertical position of the component.
rely
Specifies the vertical position of the component, relative to that of another
component.
width
height
relwidth
relheight
in_
Specifies the absolute width of the component.
anchor
Indicates which part of the component to “fix” at the given position. Possible
values are NW (default), N, NE, E, SE, S, SW, W and CENTER.
Fig. 10.20
Indicates the horizontal position of the component, relative to that of another
component.
Indicates the absolute height of the component.
Specifies the width of the component, relative to that of another component.
Specifies the height of the component, relative to that of another component.
Specifies a reference component. The newly inserted component, which must
be a sibling or a child of the reference component, is placed relative to it.
Place op tions.
 2002 Prentice Hall. All rights reserved.
54
10.11 Card Shuffling and Dealing Simulation
• Creates GUI with Button and Label
components
• Event handlers associated with button events
• Uses random number generation
 2002 Prentice Hall. All rights reserved.
55
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. 10.21: fig10_21.py
# Card shuffling and dealing program
import random
Represents
from Tkinter import
*
Card with face and suit attributes
Outline
fig10_21.py
class Card:
"""Class that represents one playing card"""
# class attributes faces and suits contain strings
# that correspond to card face and suit values
faces = [ "Ace", "Deuce", "Three", "Four", "Five",
"Six", "Seven", "Eight", "Nine", "Ten",
"Jack", "Queen", "King" ]
suits = [ "Hearts", "Diamonds", "Clubs", "Spades" ]
def __init__( self, face, suit ):
"""Card constructor, takes face and suit as strings"""
self.face = face
self.suit = suit
def __str__( self ):
"""String representation of a card"""
return "%s
of %s"
% creates
( self.face,
self.suit
)
Class
Deck
GUI card
deck shuffler
class Deck( Frame ):
"""Class to represent a GUI card deck shuffler"""
def __init__( self ):
"""Deck constructor"""
Frame.__init__( self )
self.master.title( "Card Dealing Program" )
 2002 Prentice Hall.
All rights reserved.
56
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
Outline
self.deck = [] # list of card objects
self.currentCard = 0 # index of current card
fig10_21.py
# create deck
for i in range( 52 ):
self.deck.append( Card( Card.faces[ i % 13 ],
Card.suits[ i / 13 ] ) )
Create dealButton and associate it with callback dealCard
# create buttons
self.dealButton = Button( self, text = "Deal Card",
width = 10, command = self.dealCard )
self.dealButton.grid(
= 0, column = 0 and
) associate
Createrow
shuffleButton
it with callback shuffle
self.shuffleButton = Button( self, text = "Shuffle cards",
width = 10, command = self.shuffle )
self.shuffleButton.grid( row = 0, column = 1 )
Create Label component
# create labels
self.message1 = Label( self, height = 2,
text = "Welcome to Card Dealer!" )
self.message1.grid( row = 1, columnspan = 2 )
and set height option
self.message2 = Label( self, height = 2,
text = "Deal card or shuffle deck" )
self.message2.grid( row = 2, columnspan = 2 )
self.shuffle()
Event
self.grid()
handler shuffle rearranges the order of the 52 Card objects
def shuffle( self ):
"""Shuffle the deck"""
self.currentCard = 0
 2002 Prentice Hall.
All rights reserved.
57
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
Outline
for i in range( len( self.deck ) ):
j = random.randint( 0, 51 )
# swap the cards
self.deck[ i ], self.deck[ j ] = \
Label component’s
self.deck[ j ],Set
self.deck[
i ]
fig10_21.py
text
self.message1.config( text Alter
= "DECK
IS SHUFFLED"
)
state
value of Button
self.message2.config( text = "" )
self.dealButton.config( state = NORMAL )
component
Event handler dealCard displays Card object
def dealCard( self ):
"""Deal one card from the deck"""
# display the card, if it exists
if self.currentCard < len( self.deck ):
self.message1.config(
text = self.deck[ self.currentCard ] )
self.message2.config(
text = "Card #: %d" % self.currentCard )
else:
self.message1.config( text = "NO MORE CARDS TO DEAL" )
self.message2.config( text =
"Shuffle cards to continue" )
self.dealButton.config( state = DISABLED )
self.currentCard += 1
# increment card for next turn
def main():
Deck().mainloop()
if __name__ == "__main__":
main()
 2002 Prentice Hall.
All rights reserved.
58
Outline
fig10_21.py
 2002 Prentice Hall.
All rights reserved.