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.
© Copyright 2026 Paperzz