Module 17 - Graphical User Interfaces in Python Header

Module 17 - Graphical User Interfaces in Python

Introduction to TKInter

What is Tkinter?

Tkinter is a standard GUI (Graphical User Interface) library in Python that allows developers to create desktop applications with graphical elements, such as windows, buttons, menus, and more. Tkinter is based on the Tk GUI toolkit, which originated from the Tcl programming language. As Tkinter is included with most Python installations, there's no need for additional installations, making it a widely accessible choice for GUI development.

Advantages of using Tkinter for GUI development:

Tkinter offers several advantages that make it a popular choice for building graphical interfaces:

  • Easy to Learn: Tkinter's simple and intuitive syntax makes it easy for beginners to get started with GUI development.
  • Platform Independence: Tkinter applications can run on various platforms, including Windows, macOS, and Linux, without any modifications.
  • Wide Range of Widgets: Tkinter provides a wide array of pre-built widgets that you can use to create buttons, labels, text entry fields, checkboxes, and more.
  • Customizable Appearance: Tkinter widgets can be styled and configured to match the desired look and feel of your application.
  • Event-Driven Programming: Tkinter follows an event-driven programming paradigm, where user actions (clicking buttons, typing text, etc.) trigger specific functions, enabling interactive applications.

Importing Tkinter and creating a basic window:

To start using Tkinter, you need to import the library and create a basic application window. Let's go through the steps:

Step 1: Importing Tkinter

import tkinter as tk

Step 2: Creating a Basic Window

# Create the main application window
root = tk.Tk()

# Set the window title
root.title("My First Tkinter App")

# Set the window dimensions (width x height)
root.geometry("400x300")

# Start the main event loop
root.mainloop()

In the above code:

  • We imported Tkinter using the import tkinter as tk statement, giving it the alias tk for convenience.
  • We created the main application window using tk.Tk() and assigned it to the variable root.
  • We set the title of the window using the title() method.
  • We defined the dimensions of the window using the geometry() method, specifying a width of 400 pixels and a height of 300 pixels.
  • Finally, we started the main event loop using mainloop(), which allows the window to respond to user interactions.

Upon running this code, you will see a window with the specified title and dimensions. However, it will be empty as we haven't added any widgets yet. In the next part of this unit, we will explore different types of Tkinter widgets and how to use them to create interactive user interfaces.



TKInter Widgets

Graphical User Interfaces (GUIs) consist of various elements called widgets that allow users to interact with the application. Tkinter provides a rich set of built-in widgets to design user interfaces efficiently. In this section, we will explore some commonly used widgets and their functionalities.

Labels:

Labels are used to display static text or images on the GUI. They serve as informative elements that provide instructions or descriptions to users. Labels do not allow user input and are mostly used for displaying information.

Example:

import tkinter as tk

# Create the main application window
root = tk.Tk()
root.title("Label Example")

# Create and display a label
label = tk.Label(root, text="Hello, Tkinter!")
label.pack()

# Run the Tkinter event loop
root.mainloop()

Buttons:

Buttons are interactive elements that perform actions when clicked. They are widely used to trigger functions or events within the GUI application.

Example:

import tkinter as tk

# Function to be executed when the button is clicked
def on_button_click():
label.config(text="Button clicked!")

# Create the main application window
root = tk.Tk()
root.title("Button Example")

# Create a label and a button
label = tk.Label(root, text="Press the button:")
label.pack()
button = tk.Button(root, text="Click Me!", command=on_button_click)
button.pack()

# Run the Tkinter event loop
root.mainloop()

Entry Widgets:

Entry widgets allow users to input single-line text. They are commonly used for data entry and form fields.

Example:

import tkinter as tk

# Function to get the input from the Entry widget
def get_input():
user_input = entry.get()
label.config(text=f"Your input: {user_input}")

# Create the main application window
root = tk.Tk()
root.title("Entry Example")

# Create an Entry widget and a button
entry = tk.Entry(root)
entry.pack()
button = tk.Button(root, text="Submit", command=get_input)
button.pack()
label = tk.Label(root, text="")
label.pack()

# Run the Tkinter event loop
root.mainloop()

Text Widgets:

Text widgets are used to display and edit multiline text. They provide functionalities similar to a text editor, making them suitable for displaying long texts or notes.

Example:

import tkinter as tk

# Function to display the content of the Text widget
def display_text():
text_content = text_widget.get("1.0", tk.END)
label.config(text=text_content)

# Create the main application window
root = tk.Tk()
root.title("Text Widget Example")

# Create a Text widget and a button
text_widget = tk.Text(root, height=5, width=30)
text_widget.pack()
button = tk.Button(root, text="Display Text", command=display_text)
button.pack()
label = tk.Label(root, text="")
label.pack()

# Run the Tkinter event loop
root.mainloop()

Checkboxes:

Checkboxes are used for presenting multiple options, and users can select one or more choices simultaneously.

Example:

import tkinter as tk

# Function to display selected options
def show_selected():
selected_options = [option.get() for option in checkboxes]
label.config(text=f"Selected: {', '.join(selected_options)}")

# Create the main application window
root = tk.Tk()
root.title("Checkbox Example")

# Create and display checkboxes
options = ["Option 1", "Option 2", "Option 3"]
checkboxes = [tk.StringVar() for _ in range(len(options))]
for idx, option in enumerate(options):
tk.Checkbutton(root, text=option, variable=checkboxes[idx]).pack()

# Create a button and a label
button = tk.Button(root, text="Show Selected", command=show_selected)
button.pack()
label = tk.Label(root, text="")
label.pack()

# Run the Tkinter event loop
root.mainloop()

Radio Buttons:

Radio buttons present a list of options, and users can choose only one option from the available choices.

Example:

import tkinter as tk

# Function to display the selected option
def show_selected():
selected_option = radio_var.get()
label.config(text=f"Selected: {selected_option}")

# Create the main application window
root = tk.Tk()
root.title("Radio Button Example")

# Create and display radio buttons
options = ["Option 1", "Option 2", "Option 3"]
radio_var = tk.StringVar()
for option in options:
tk.Radiobutton(root, text=option, variable=radio_var, value=option).pack()

# Create a button and a label
button = tk.Button(root, text="Show Selected", command=show_selected)
button.pack()
label = tk.Label(root, text="")
label.pack()

# Run the Tkinter event loop
root.mainloop()

Listboxes:

Listboxes display a list of items from which users can select one or more options.

Example:

import tkinter as tk

# Function to display the selected item(s)
def show_selected():
selected_items = [listbox.get(idx) for idx in listbox.curselection()]
label.config(text=f"Selected: {', '.join(selected_items)}")

# Create the main application window
root = tk.Tk()
root.title("Listbox Example")

# Create a listbox and populate it with items
listbox = tk.Listbox(root, selectmode=tk.MULTIPLE)
for item in ["Item 1", "Item 2", "Item 3", "Item 4"]:
listbox.insert(tk.END, item)
listbox.pack()

# Create a button and a label
button = tk.Button(root, text="Show Selected", command=show_selected)
button.pack()
label = tk.Label(root, text="")
label.pack()

# Run the Tkinter event loop
root.mainloop()

Frames:

Frames are containers that allow organizing widgets within a window. They help in achieving a better layout by grouping related elements together.

Example:

import tkinter as tk

# Create the main application window
root = tk.Tk()
root.title("Frame Example")

# Create and pack two frames
frame1 = tk.Frame(root, padx=10, pady=10)
frame1.pack(side=tk.LEFT)
frame2 = tk.Frame(root, padx=10, pady=10)
frame2.pack(side=tk.RIGHT)

# Add widgets to frames
tk.Label(frame1, text="This is Frame 1").pack()
tk.Label(frame2, text="This is Frame 2").pack()

# Run the Tkinter event loop
root.mainloop()

In this section, you have learned about some of the essential Tkinter widgets and how to use them in your GUI applications. Tkinter offers a wide range of widgets, and you can combine them creatively to design interactive and user-friendly interfaces. In the next section, we will cover the positioning of these widgets within the application window using different layout managers.



Positioning Widgets

Positioning widgets within a window is a crucial aspect of GUI development. Tkinter provides three main geometry managers to control the layout of widgets: pack(), grid(), and place(). Each manager offers different strategies for arranging widgets, and you can choose the one that best fits your application's needs.

Pack Geometry Manager:

The pack() geometry manager organizes widgets in a horizontal or vertical stack. It is simple to use and automatically handles the positioning based on the order in which widgets are packed. The pack manager is suitable for basic layouts or when you want to place widgets sequentially without much complexity.

Example:

import tkinter as tk

root = tk.Tk()

label1 = tk.Label(root, text="Label 1")
label2 = tk.Label(root, text="Label 2")
label3 = tk.Label(root, text="Label 3")

label1.pack()
label2.pack()
label3.pack()

root.mainloop()

Grid Geometry Manager:

The grid() geometry manager allows you to create more complex layouts by organizing widgets in rows and columns. You can use the row and column options to specify where the widget should be placed. Additionally, the rowspan and columnspan options enable widgets to span multiple rows or columns, providing even more flexibility.

Example:

import tkinter as tk

root = tk.Tk()

label1 = tk.Label(root, text="Label 1")
label2 = tk.Label(root, text="Label 2")
label3 = tk.Label(root, text="Label 3")

label1.grid(row=0, column=0)
label2.grid(row=0, column=1)
label3.grid(row=1, column=0, columnspan=2)

root.mainloop()

Place Geometry Manager:

The place() geometry manager allows you to position widgets precisely using absolute coordinates or relative positioning. While it gives you more control over the widget's placement, it requires manual handling and can be less flexible compared to the other managers.

Example:

import tkinter as tk

root = tk.Tk()

label1 = tk.Label(root, text="Label 1")
label2 = tk.Label(root, text="Label 2")
label3 = tk.Label(root, text="Label 3")

label1.place(x=20, y=30)
label2.place(x=50, y=80)
label3.place(x=100, y=150)

root.mainloop()

Choosing the Right Geometry Manager:

The choice of a geometry manager depends on your application's complexity and layout requirements. For simple interfaces with a few widgets, the pack() manager might be sufficient. For more structured and organized layouts, the grid() manager is often preferred. The place() manager is best suited for scenarios where you need precise widget positioning.

You can also combine different geometry managers within frames to achieve even more intricate layouts for your GUI applications.

Summary:

Positioning elements within a window is essential in GUI development to create visually appealing and user-friendly interfaces. Tkinter provides three geometry managers (pack(), grid(), and place()) to help you control the layout of widgets. Choose the most suitable manager based on your application's complexity and desired widget arrangement. Experiment with different layouts and continue exploring Tkinter's features to enhance your GUI development skills in Python.



Interacting with Functions

Graphical User Interface (GUI) applications are not just about displaying information; they also need to respond to user interactions and perform actions accordingly. In this section, we will explore how to connect Tkinter widgets with Python functions to achieve dynamic and interactive behavior in your GUI applications.

Binding Functions to Events

In Tkinter, events are user actions like button clicks, mouse movements, or key presses. To respond to these events, we can bind functions to them. When the event occurs, the associated function will be called, allowing us to perform specific tasks.

Let's see how to bind a function to a button click event:

import tkinter as tk

def on_button_click():
print("Button clicked!")

root = tk.Tk()
button = tk.Button(root, text="Click Me", command=on_button_click)
button.pack()

root.mainloop()

In this example, we defined a function on_button_click() that prints a message when the button is clicked. We then created a button widget and used the command parameter to bind the function to the button's click event.

Handling User Input

User input is essential for most GUI applications, whether it's entering text, selecting options, or providing values. We can retrieve user input from various widgets like Entry, Listbox, or Text widgets.

Let's create an example to get user input from an Entry widget:

import tkinter as tk

def greet_user():
name = entry.get()
if name.strip():
greeting = f"Hello, {name}!"
output_label.config(text=greeting)

root = tk.Tk()
entry = tk.Entry(root)
entry.pack()

greet_button = tk.Button(root, text="Greet", command=greet_user)
greet_button.pack()

output_label = tk.Label(root, text="")
output_label.pack()

root.mainloop()

In this example, we created an Entry widget to get the user's name. When the "Greet" button is clicked, the greet_user() function retrieves the name from the Entry widget and displays a personalized greeting.

Updating Widgets Dynamically

GUI applications often require updating widgets dynamically based on user actions or other factors. For example, you might want to change the text of a label or update a listbox with new data.

Let's create a simple example that updates a label's text based on a button click:

import tkinter as tk

def update_label_text():
new_text = "Label text updated!"
label.config(text=new_text)

root = tk.Tk()
label = tk.Label(root, text="Click the button to update me.")
label.pack()

update_button = tk.Button(root, text="Update Label", command=update_label_text)
update_button.pack()

root.mainloop()

In this example, when the "Update Label" button is clicked, the update_label_text() function updates the label's text dynamically.

Creating a Complete GUI Application

Now that you have learned how to bind functions to events, handle user input, and update widgets dynamically, let's create a complete GUI application that combines these concepts.

For example, we can build a simple calculator application with basic arithmetic operations:

import tkinter as tk

def calculate_result():
try:
num1 = float(entry_num1.get())
num2 = float(entry_num2.get())
operator = operator_var.get()

if operator == "+":
result = num1 + num2
elif operator == "-":
result = num1 - num2
elif operator == "*":
result = num1 * num2
elif operator == "/":
result = num1 / num2

result_label.config(text=f"Result: {result}")
except ValueError:
result_label.config(text="Error: Invalid input!")

root = tk.Tk()
root.title("Simple Calculator")

entry_num1 = tk.Entry(root)
entry_num1.pack()

operator_var = tk.StringVar()
operator_choices = ["+", "-", "*", "/"]
operator_var.set("+") # Set the initial operator to '+'
operator_menu = tk.OptionMenu(root, operator_var, *operator_choices)
operator_menu.pack()

entry_num2 = tk.Entry(root)
entry_num2.pack()

calculate_button = tk.Button(root, text="Calculate", command=calculate_result)
calculate_button.pack()

result_label = tk.Label(root, text="")
result_label.pack()

root.mainloop()

In this example, the application takes two numeric inputs, an operator choice, and displays the calculated result when the "Calculate" button is clicked.

Feel free to enhance this example or create your own unique GUI applications with Tkinter and Python functions!

Conclusion:

In this section, you have learned how to make your Tkinter GUI applications interactive by binding functions to events, handling user input, and updating widgets dynamically. By combining these techniques, you can create versatile and functional GUI applications tailored to your needs. Keep experimenting with Tkinter and exploring its various capabilities to build engaging and user-friendly interfaces. Happy coding!

Videos for Module 17 - Graphical User Interfaces in Python

17-1: Introduction to Module 17 (2:13)

17-2: Python GUI Apps With TKInter (4:09)

17-3: TKInter Widget Hierarchy (4:36)

17-4: TKInter Event Loop & Event Driven Model (5:10)

17-5: Introducing TKInter Widgets (14:27)

17-6: TKInter Label Widget (3:59)

17-7: TKInter Button Widget (2:21)

17-8: TKInter Checkbox and Radio Button Widgets (3:20)

17-9: TKInter Entry Widget and Layout (6:50)

17-10: Adding a Command to a TKInter Button (6:01)

17-11: TKInter Modal Windows (2:58)

17-12: Showing Pillow Images in TKInter Using TKImage (10:04)

17-13: Prototyping TKInter Interfaces Using ChatGPT and AI (13:10)

Key Terms for Module 17 - Graphical User Interfaces in Python

No terms have been published for this module.

Quiz Yourself - Module 17 - Graphical User Interfaces in Python

Test your knowledge of this module by choosing options below. You can keep trying until you get the right answer.

Skip to the Next Question 

Activities for this Module

A17 - Python GUI App

The Challenge

Take any of the previous assignments for this class, and create a GUI for it using TKInter.  I highly recommend using a previous assignment that made use of functions and modules -- You will find these much easier to integrate into a GUI, because the functionality is grouped more efficiently.

Submission Type

Please submit the complete program as a .py file.