Lec 23 GUIs
Assignment Updates
Stuff due soon:
- HW7 Due 5/15
- Capstone Project Presentations 5/16 and 5/17
Slides
- Section 1, 6
- Section 2, 3, 4, 5
Resources
- TKinter Documentation
- TKinter Tutorial
- Download gui.py
- This code is a simple GUI that displays a label and a button using TKinter
- Download event.py
- This code has a button that triggers an event when clicked
- Download stopwatch.py
- This code is a stopwatch that counts up when you click the start button
- Download stopwatch_lap.py
- This code is a stopwatch that counts up when you click the start button. It also has a lap button that records the current time and displays it in a list
Notes
Topics
- GUIs
- Events
- TKinter
GUIs
- GUI = Graphical User Interface
- A GUI is a program that has a window with buttons, text boxes, etc.
- Example: A web browser is a GUI
TKinter
- TKinter is a Python library for creating GUIs
- We can use TKinter to create a GUI
- We can create a window
- We can add buttons to the window
- We can add text boxes to the window
- We can add other widgets to the window
- How do we do this?
- First, we need to import the TKinter library
- Then, we need to create a window
- Then, we need to add widgets to the window
- Finally, we need to start the main loop
- The main loop is a loop that runs forever
- Example:
from tkinter import Tk, Label, Button
# Create the main window: 400x250 pixels, titled 'My App'
window = Tk()
window.title("My App")
window.geometry("400x250")
button = Button(
text="Click Me!", # Text to display on the button
width=25, # Width
height=5, # Height
bg="blue", # Button color
fg="yellow", # Text color
)
# adds the button to the window
button.place(x=180, y=100)
label = Label(
text="Hello World!", # Text to display
font=("Arial", 24, "bold") # Font (font, size, style)
)
# Adds the label to the window
label.place(x=180, y=50)
# Starts the GUI
window.mainloop()
Events
- On a GUI, when you click a button, something happens
- Currently, we write code that immediately executes
- How do we write code that executes when something happens?
- We can do this with events
- An event is something that happens
- Clicking a button is an event
- Pressing a key is an event
- We can write code that executes when an event happens
- The code that executes when an event happens is called an event handler
- Examples:
- Code that executes when a button is clicked
- Code that executes when a key is pressed
- An event is something that happens
- How do we do this?
- First, we need an way to create an event
- Example: A button that can be clicked
- Then, we need to write code that executes when the event happens
- This is the event handler
- Example: A print statement that prints 'Button clicked'
- First, we need an way to create an event
- Example:
from tkinter import Tk, Button
# Create the main window: 400x250 pixels, titled 'A Button', white background
ws = Tk()
ws.geometry('400x250')
ws.title('A Button')
ws.config(bg='#ffffff')
# A function that prints 'Button clicked' to the console
def button_clicked():
print('Button clicked')
# Create a button that calls the button_clicked function when clicked
# In this case, the event of clicking the button is handled by the
# button_clicked function
btn = Button(ws, text='Click Me!', command=button_clicked)
# Place the button in the main window
btn.place(x=180, y=100)
# Starts the GUI and listens for events
ws.mainloop()
Stopwatch
- We can use events to create a stopwatch
- A stopwatch is a program that counts the number of seconds that have passed
- It has a start button, a stop button, and a reset button
- When the start button is clicked, the stopwatch starts counting
- When the stop button is clicked, the stopwatch stops counting
- When the reset button is clicked, the stopwatch resets to 0
- Example:
from tkinter import Tk, Label, Button
class Stopwatch:
"""A simple stopwatch GUI app."""
def __init__(self):
# Sets the background color of the main window (to white)
BACKGROUND = '#ffffff'
# Create the main window: 400x250 pixels, titled 'Stopwatch'
ws = Tk()
ws.geometry('400x250')
ws.title('Stopwatch')
ws.config(bg=BACKGROUND)
ws.resizable(False, False)
# Lbl is the label that displays the count
lbl = Label(ws, text="00:00", fg="black",
bg=BACKGROUND, font="Verdana 40 bold")
# start_btn is the button that starts the stopwatch
start_btn = Button(ws, text='Start', width=15, command=self.StartTimer)
# stop_btn is the button that stops the stopwatch
stop_btn = Button(ws, text='Stop', width=15,
state='disabled', command=self.StopTimer)
# reset_btn is the button that resets the stopwatch
reset_btn = Button(ws, text='Reset', width=15,
state='disabled', command=self.ResetTimer)
# Moves the buttons and label to the correct position
lbl.place(x=120, y=60)
start_btn.place(x=30, y=200)
stop_btn.place(x=150, y=200)
reset_btn.place(x=270, y=200)
# Count keeps track of the time elapsed
self.count = 0
# Running keeps track of if the stopwatch is running
self.running = None
# Elements in the GUI
self.ws = ws
self.lbl = lbl
self.start_btn = start_btn
self.stop_btn = stop_btn
self.reset_btn = reset_btn
# Starts the GUI
ws.mainloop()
def Count(self):
"""Adds one second to the count and updates the label. Runs every second."""
# If the stopwatch is not running, don't do anything
if self.running is None:
return
# Updates the count and label
self.count += 1
secs = int(self.count % 60)
mins = int(self.count // 60)
self.lbl['text'] = f'{mins:02}:{secs:02}'
# Sets an event to call Count again after 1 second
self.running = self.ws.after(1000, self.Count)
def StartTimer(self):
"""Starts the stopwatch."""
# Creates an event to call Count after 1 second
self.running = self.ws.after(1000, self.Count)
# Enables and disables the correct buttons
self.start_btn['state'] = 'disabled'
self.stop_btn['state'] = 'normal'
self.reset_btn['state'] = 'normal'
def StopTimer(self):
"""Stops the stopwatch. Does not reset the count."""
# Cancels the event calling Count
self.running = self.ws.after_cancel(self.running)
# Enables and disables the correct buttons
self.start_btn['state'] = 'normal'
self.stop_btn['state'] = 'disabled'
self.reset_btn['state'] = 'normal'
def ResetTimer(self):
"""Resets the stopwatch. Also stops the stopwatch."""
# Cancels the event calling Count and resets the count
self.running = None
self.count = 0
# Resets the label and enables/disables the correct buttons
self.lbl['text'] = '00:00'
self.start_btn['state'] = 'normal'
self.stop_btn['state'] = 'disabled'
self.reset_btn['state'] = 'disabled'
# Creates the stopwatch
Stopwatch()