260 likes | 482 Views
Guide to Programming with Python. Chapter Ten GUI Development: The Mad Lib Program . Objectives. Events-driven programming! Work with a GUI toolkit Create and fill frames Create and use widgets Buttons text entries text boxes check buttons radio buttons Layout of the widget
E N D
Guide to Programming with Python Chapter Ten GUI Development: The Mad Lib Program
Objectives • Events-driven programming! • Work with a GUI toolkit • Create and fill frames • Create and use widgets • Buttons • text entries • text boxes • check buttons • radio buttons • Layout of the widget • Create event handlers and bind (associate) events with event handlers
Understanding Event-Driven Programming • Event-driven program: A program that responds to actions regardless of the order in which they occur (vs structured programming) • Event: Something that happens involving a program's objects (mouse moves over; click of a button, etc) • Event handler: Code that runs when a specific event occurs • Bind: To associate an event with an event handler • Event loop: A loop that checks for events and calls appropriate event handlers when they occur • GUI programs traditionally event-driven: the users control the flow of the program
The Mad Lib Program Guide to Programming with Python
Buttons’ on Strike from Tkinter import * root = Tk() #a root window, upon which other GUI elements can be added root.title("Simple GUI Demo") #add title root.geometry("400x200") #change the size of the window app = Frame(root) #create a frame, upon which other Widgets can be added app.grid() #need to invoke grid() method button1 = Button(app, text = "I am button #1") button1.grid() button2 = Button(app) button2.grid() button2.configure(text = "I am button #2”) button3 = Button(app, text = "I am button #3") button3.grid() button3['text'] = "I am button #3” root.mainloop() #must start up the window's event loop!!! (I) (II) (III) (IV)
(I) Creating a Root Window from Tkinter import * root = Tk() root.title("Simple GUI") root.geometry("200x100”) # takes a string • To create a root window, instantiate object of the Tkinter class Tk • Tkinter is a GUI module • Imports all Tkinter into global scope • Normally, avoid this kind of import * • Some modules designed to be imported this way • Saves typing and makes for cleaner code (no need to prefix the module name) • Modify a window’s appearance by changing title and geometry
(II) Creating a Frame app = Frame(root) app.grid() • Master: A widget that contains other widgets • Layout Manager: Controls arrangement of widgets • Frame is widget that can hold other widgets • When creating widget, must pass its master to constructor of new object • Here, root is master that contains app • grid() • Method that all widgets have • Associated with grid layout manager Guide to Programming with Python
(III) Using Widgets button1 = Button(app, text = "I am button #1") button1.grid() • Widget: GUI elements (short for "window gadget") • Button widget • Is a button in GUI • Can be activated by user to perform some action • Button Class • For a button widget • Master is first argument passed to constructor • text parameter for widget's text • grid() method invoked ensures widget visible Guide to Programming with Python
(VI) Entering a Root Window’s Event Loop root.mainloop() • Root window's event loop entered • Window stays open, waiting to handle events Guide to Programming with Python
Creating a GUI Using a Class • Organizing code into classes can make programming easier • Often beneficial to write larger GUI programs in OOP style Guide to Programming with Python
Defining the Application Class class Application(Frame): def __init__(self, master): # create a frame (need to get master 'root’) Frame.__init__(self, master) self.grid() self.CreateWidgets() def CreateWidgets(self): # create button #1 self.button1 = Button(self, text = "I am button #1”) self.button1.grid() … def main(): root = Tk() root.title("Simple GUI Demo") root.geometry("400x200”) app = Application(root) root.mainloop() main() # Application object is just specialized type of Frame object (derived from Frame)
Placing a Widget with the Grid Layout Manager Grid layout manager lets you place widgets at specific locations by treating frame as a grid of cells at row and column numbers
Widgets Have grid() Method def create_widgets(self): self.inst_lbl = Label(self, text = "Enter password for the secret of longevity") self.inst_lbl.grid(row = 0, column = 0, columnspan = 2, sticky = W) • grid()method • rowtakes integer, defines row object placed in master • columntakes integer, defines column object placed in master • columnspantakes integer, defines width in columns • stickytakes constants (including N, S, E, W), positions widget within cell Guide to Programming with Python
Binding Widgets and Event Handlers • So far, GUI programs haven't had event handlers • Widgets are like light fixtures without electrical wiring • Write event handlers and bind them with events Guide to Programming with Python
Buttons That Do Something class Application(Frame): def __init__(self, master): ... self.bttn_clicks = 0 #initialize the button_clicks self.create_widgets() def create_widgets(self): self.button1 = Button(self, text = "Button #1 does nothing") self.button1.grid() self.button2 = Button(self) self.button2["text"] = "Button #2 counts: clicks=" + str(self.bttn_clicks) self.button2["command"] = self.update_count self.button2.grid() self.button3 = Button(self) self.button3.configure(text = "Button #3 resets") self.button3["command"] = self.clear_count self.button3.grid() def update_count(self): self.bttn_clicks += 1 self.button2["text"] = "Button #2 counts: clicks=" + str(self.bttn_clicks) def clear_count(self): self.bttn_clicks = 0 self.button2["text"] = "Button #2 counts: clicks=" + str(self.bttn_clicks)
Creating the Event Handler def update_count(self): self.bttn_clicks += 1 self.button2["text"] = "Button #2 counts: clicks=" +\ str(self.bttn_clicks) • update_count() increments total number of button clicks and changes text to reflect new total Guide to Programming with Python
Binding the Event Handler def create_widgets(self): self.button1 = Button(self, text = "Button #1 does nothing") self.button1.grid() self.button2 = Button(self) self.button2["text"] = "Button #2 counts: clicks=" +\ str(self.bttn_clicks) self.button2["command"] = self.update_count self.button2.grid() • Set widget’s commandoption to bind activation of widget with event handler • commandoption bound to update_count()method • When button clicked, update_count()invoked Guide to Programming with Python
The Longevity Program Label Label Entry Button Text How the widgets are created? How the widgets are arranged? How the “Submit” button can do something?
class Application(Frame): def __init__(self, master): … def create_widgets(self): self.inst_lbl = Label(self, text = "Enter password for the secret of longevity") self.inst_lbl.grid(row = 0, column = 0, columnspan = 2, sticky = W) self.pw_lbl = Label(self, text = "Password: ") self.pw_lbl.grid(row = 1, column = 0, sticky = W) self.pw_ent = Entry(self) self.pw_ent.grid(row = 1, column = 1, sticky = W) self.submit_bttn = Button(self, text = "Submit", command = self.reveal) self.submit_bttn.grid(row = 2, column = 0, sticky = W) self.secret_txt = Text(self, width = 35, height = 5, wrap = WORD) self.secret_txt.grid(row = 3, column = 0, columnspan = 2, sticky = W) def reveal(self): contents = self.pw_ent.get() if contents == "secret": #get the message here self.secret_txt.delete(0.0, END) self.secret_txt.insert(0.0, message) Label Label Entry Button Text
The Movie Chooser Program Label Checkbutton Text How to create the check buttons and associate them with the event?
class Application(Frame): def __init__(self, master): … def create_widgets(self): … self.likes_comedy = BooleanVar() Checkbutton(self, text = "Comedy", variable = self.likes_comedy, command = self.update_text ).grid(row = 2, column = 0, sticky = W) … self.results_txt = Text(self, width = 40, height = 5, wrap = WORD) self.results_txt.grid(row = 5, column = 0, columnspan = 3) def update_text(self): #get the message, likes if self.likes_comedy.get(): likes += "You like comedic movies.\n” …. self.results_txt.delete(0.0, END) self.results_txt.insert(0.0, likes)
Using Check Buttons self.likes_comedy = BooleanVar() Checkbutton(self, text = "Comedy", variable = self.likes_comedy, command = self.update_text ).grid(row = 2, column = 0, sticky = W) ... if self.likes_comedy.get(): likes += "You like comedic movies.\n” • variable takes BooleanVar for status of check button • BooleanVar • Special class from Tkinter module • Can reflect check button’s status (Can’t access the value directly; Must invoke object’s get() method • command takes function or method to call when check button is checked or unchecked
Using Radio Buttons • Radio buttons allow user to select one from a group of choices Radio buttons (instead of check buttons) The Movie Chooser 2 Program Guide to Programming with Python
Using Radio Buttons self.favorite = StringVar() Radiobutton(self, text = "Comedy", variable = self.favorite, value = "comedy.", command = self.update_text ).grid(row = 2, column = 0, sticky = W) ... message += self.favorite.get() • StringVar • Special class from Tkinter module; required by Radiobutton objects • Can reflect status of a group of radio buttons • variable parameter gets StringVar self.favorite • The same StringVar object passed to all the radio buttons of the same group • When radio button is selected, StringVar assigned string referenced by object’s value option • When Comedy radio button selected, self.favorite gets "comedy."
Summary • A GUI is a graphical user interface • A widget, short for window gadget, is a GUI element • A master widget (frame) contains other widgets • A layout manager controls the arrangement of widgets (grid()) • An event-driven program responds to actions regardless of the order in which they occur • An event is something that happens involving a program’s objects, and needs to be associated with event handlers Guide to Programming with Python