300 likes | 470 Views
Computer Science 111. Fundamentals of Programming I Graphical User Interfaces. Terminal-Based User Interface. Accepts textual input from the keyboard Processes the input Displays output as text on the monitor screen. Graphical User Interface (GUI).
E N D
Computer Science 111 Fundamentals of Programming I Graphical User Interfaces
Terminal-Based User Interface • Accepts textual input from the keyboard • Processes the input • Displays output as text on the monitor screen
Graphical User Interface (GUI) • Supports user interaction by allowing direct manipulation of graphical elements with a pointing device (mouse)
Graphical User Interface (GUI) • Supports user interaction by allowing direct manipulation of graphical elements with a pointing device (mouse) • Graphical elements or widgets are • Command buttons • Drop-down menus • Data entry fields • Scrolling list boxes • Multiple windows • Labels and images for decoration
The Model/View Pattern Data Model View (User Interface) The data model consists of software components that manage a system’s data The view consists of software components that allow human users to view and interact with the data model
Event-Driven Programming • Set up a window with its widgets • Connect it to a data model • Wait for users to press buttons, enter text, drag the mouse, etc. • Respond to these events by running methods that update the data model and the view
Resources in the tkinter Module Top-level windows Frame Window objects (widgets) Label Button Entry PhotoImage Text
Basics of GUI Programming • from tkinter import* • Define a window class as a subclass of Frame • The __init__ method initializes the parent frame, creates the widgets, and places them in the window • Define the methods to handle events • Define a main function that instantiates the window class and runs its mainloop method
Display a Greeting as a Label from Tkinter import * class Demo1(Frame): def __init__(self): Frame.__init__(self) self.master.title("Demo 1") self.grid() self._label = Label(self, text = "Hello world!") self._label.grid() def main(): Demo1().mainloop() The grid method positions a widget in a frame A Label object has a text attribute
Display a Captioned Image class Demo2(Frame): def __init__(self): Frame.__init__(self) self.master.title("Demo 2") self.grid() self._image = PhotoImage(file = "smokey.gif") self._imageLabel = Label(self, image = self._image) self._imageLabel.grid() self._textLabel = Label(self, text = "Smokey the cat") self._textLabel.grid() def main(): Demo2().mainloop() The image attribute takes a PhotoImage value
Command Buttons class Demo5(Frame): def __init__(self): Frame.__init__(self) self.master.title("Demo 5") self.grid() self._label = Label(self, text = "Hello") self._label.grid() self._button = Button(self, text = "Click me", command = self._switch) self._button.grid() def main(): Demo5().mainloop() The Button object has a text attribute and a command attribute
Handling Events class Demo5(Frame): def _switch(self): if self._label["text"] == "Hello": self._label["text"] = "Goodbye" else: self._label["text"] = "Hello" def main(): Demo5().mainloop() The _switch method is automatically called when the button is pressed
Classes and Relationships Frame Demo Label Button
Data Entry • The user enters data in a text field • When the user clicks the button, input data is read from the field, processed, and output data is sent back to the field
Text Entry Fields • An Entry widget can input or output a single line of text • The string datum for an Entry widget is held in an associated StringVar object • Setting the text in a StringVar automatically updates the associated Entry widget
Setting Up the Entry Widget def __init__(self): """Initialize the frame and its grid.""" Frame.__init__(self) self.master.title("Testing Data Entry") self.grid() self.nameVar = StringVar() self.nameLabel = Label(self, text = "Your Name") self.nameLabel.grid() self.nameEntry = Entry(self, justify = "center", textvariable = self.nameVar) self.nameEntry.grid() self.clicker = Button(self, text = "Make uppercase") self.clicker['command'] = self.clickResponse self.clicker.grid() An Entry object’s textvariable attribute is the StringVar created earlier
Responding to the Button Click def clickResponse(self): """Event handler for the button.""" userString = self.nameVar.get() self.nameVar.set(userString.upper()) The methods get and set manipulate the StringVar’s data (and indirectly, the Entry’s data)
A Banking System BankManager SavingsAccount ATM * Bank File storage
Model/View Pattern • Classes in the data model, such as SavingsAccount and Bank, manage the application’s data • Classes in the view, such as ATM and BankManager, present the data to users and handle their interactions with the application
Model/View/Controller Pattern GUI-based, event-driven programs can be further decomposed by gathering code to handle user interactions into a third component called the controller Manages data Displays data View Model Controller Responds to user events
A Simple Example: Temperature Conversion ConvertGUI A thermometer object tracks a temperature value and includes methods for setting and getting in either degrees Fahrenheit or degrees Celsius Thermometer
Steps in the Program • Define a subclass of Frame for the main window • Create an instance of the data model (thermometer) • Create an instance of the GUI class and pass it the data model • Start the main loop
Boilerplate for Most MVC Apps from tkinter import * # From the model’s module import the model class # Definition of the main window class goes here def main(): # Instantiate the model # Instantiate the main window class, passing it the model # Run mainloop on the main window object
F/C Conversion from tkinter import * from thermometer import Thermometer # Definition of the main window class goes here def main(): model = Thermometer() view = ConvertGUI(model) view.mainloop() main()
The GUI Class and init class ConvertGUI(Frame): def __init__(self, model): """Initialize the frame and its grid.""" Frame.__init__(self) self.master.title("Fahrenheit/Celsius Converter") self.grid() self.model = model # Instantiate and place the widgets in the window Establish a permanent reference to the data model
Set up the View class ConvertGUI(Frame): self.fahrVar = DoubleVar() self.celsiusVar = DoubleVar() self.fahrVar.set(self.model.getFahrenheit()) self.celsiusVar.set(self.model.getCelsius()) self.fahrLabel = Label(self, text = "Fahrenheit", fg = "red") self.fahrLabel.grid(row = 0, column = 0) self.fahrEntry = Entry(self, textvariable = self.fahrVar, justify = CENTER) self.fahrEntry.grid(row = 1, column = 0) # etc. Goto data model to get data for initial display
Set up the Controller class ConvertGUI(Frame): # Other widgets set up here. self.toCelsiusButton = Button(self, text = ">>>>") self.toCelsiusButton['command'] = self.toCelsiusResponse self.toCelsiusButton.grid(row = 2, column = 0) self.toFahrButton = Button(self, text = "<<<<") self.toFahrButton['command'] = self.toFahrResponse self.toFahrButton.grid(row = 2, column = 1) The controller consists of the methods that respond to button clicks They are associated with the relevant buttons in the view
Define a Controller Method class ConvertGUI(Frame): def toCelsiusResponse(self): """Event handler for the toCelsius button.""" fahr = self.fahrVar.get() self.model.setFahrenheit(fahr) celsius = self.model.getCelsius() self.celsiusVar.set(round(celsius, 2)) Input step: event handler method gets data from the view and sends it to the model
Define a Controller Method class ConvertGUI(Frame): def toCelsiusResponse(self): """Event handler for the toCelsius button.""" fahr = self.fahrVar.get() self.model.setFahrenheit(fahr) celsius = self.model.getCelsius() self.celsiusVar.set(round(celsius, 2)) Output step: event handler method then gets data from the model and sends it to the view
The Other Controller Method class ConvertGUI(Frame): def toFahrResponse(self): """Event handler for the toFahr button.""" celsius = self.celsiusVar.get() self.model.setCelsius(celsius) fahr = self.model.getFahrenheit() self.fahrVar.set(round(fahr, 2)) Most controllers consist of method definitions to handle distinct events