GUIs and automation
A GUI (graphical user interface) is a program with windows, buttons and text boxes instead of a black terminal. Automation means letting Python do repetitive office work: filling Excel sheets, making certificates or renaming hundreds of files.
Tkinter comes with Python on Windows, so a GUI needs nothing extra to install.
Your first Tkinter window
import tkinter as tk
root = tk.Tk()
root.title("My First App")
root.geometry("300x150") # width x height in pixels
tk.Label(root, text="Hello, Tkinter!", font=("Arial", 14)).pack(pady=20)
root.mainloop() # show the window and wait for clicks
mainloop() must be the last line: it keeps the window open and responds to the user until the window is closed.
Common widgets
| Widget | What it is |
|---|---|
Label | text or an image the user cannot edit |
Entry | a one-line text box |
Button | a button that runs a function when clicked |
Text | a multi-line text box |
Checkbutton / Radiobutton | tick boxes and one-of-many options |
Listbox | a list to choose from |
messagebox | pop-up messages (from tkinter import messagebox) |
Layout managers: pack and grid
pack()stacks widgets one after another, top to bottom by default.grid(row=, column=)places widgets in rows and columns, like a table. It suits forms best.
Do not mix pack and grid in the same window or frame.
Read inputs, calculate, show the result
import tkinter as tk
def calculate():
try:
bill = float(bill_box.get())
tip = bill * 0.10
result.config(text=f"Tip: Rs {tip:.2f} Total: Rs {bill + tip:.2f}")
except ValueError:
result.config(text="Please enter a number")
root = tk.Tk()
root.title("Tip Calculator")
tk.Label(root, text="Bill amount").grid(row=0, column=0, padx=8, pady=8)
bill_box = tk.Entry(root)
bill_box.grid(row=0, column=1, padx=8)
tk.Button(root, text="Calculate", command=calculate).grid(row=1, column=0, columnspan=2)
result = tk.Label(root, text="")
result.grid(row=2, column=0, columnspan=2, pady=8)
root.mainloop()
entry.get()reads what was typed (always a string).command=calculatepasses the function without brackets; Tkinter calls it on each click.label.config(text=...)changes what a label shows.
Timers with after()
Never use time.sleep() in a GUI: it freezes the window. Use after(milliseconds, function) to run a function later:
seconds = 0
def tick():
global seconds
seconds += 1
clock.config(text=str(seconds))
root.after(1000, tick) # run tick again in 1 second
root = tk.Tk()
clock = tk.Label(root, text="0", font=("Arial", 32))
clock.pack(padx=40, pady=20)
root.after(1000, tick)
root.mainloop()
Automating Excel with openpyxl
from openpyxl import Workbook, load_workbook # pip install openpyxl
wb = Workbook()
ws = wb.active
ws.title = "Marks"
ws.append(["Name", "Marks"]) # one row
for row in [("Asha", 91), ("Ravi", 78)]:
ws.append(row)
ws["D1"] = "Average"
ws["D2"] = "=AVERAGE(B2:B3)" # a real Excel formula
wb.save("marks.xlsx")
wb = load_workbook("marks.xlsx")
for name, marks in wb["Marks"].iter_rows(min_row=2, values_only=True):
print(name, marks)
Generate certificates with Pillow
from PIL import Image, ImageDraw, ImageFont # pip install pillow
for name in ["Asha Kumari", "Ravi Kumar"]:
img = Image.open("certificate_template.png")
draw = ImageDraw.Draw(img)
font = ImageFont.truetype("arial.ttf", 60)
draw.text((600, 420), name, font=font, fill="navy", anchor="mm")
img.save(f"certificates/{name}.png")
One loop makes a certificate for every student in a list or an Excel sheet.
Rename hundreds of files in one go
from pathlib import Path
for i, photo in enumerate(sorted(Path("photos").glob("*.jpg")), start=1):
photo.rename(photo.with_name(f"trip_{i:03}.jpg")) # trip_001.jpg, trip_002.jpg ...
Test a renaming script on a copy of the folder first: a mistake renames every file at once.
Common mistakes
- Writing
command=calculate(): the brackets call the function once at start-up instead of on each click. - Forgetting
mainloop(), so the window flashes and closes. - Using
time.sleep()inside a GUI, which freezes it. - Forgetting
wb.save(...)after changing an Excel workbook.
Key points
tk.Tk()makes a window; widgets are placed withpack()orgrid();mainloop()runs it.- Buttons take
command=functionwithout brackets;entry.get()reads input. after()schedules work without freezing the window.openpyxl,Pillowandpathlibautomate Excel, images and files.
Practice questions
1. Why must root.mainloop() be the last line of a Tkinter program?
It keeps the window open and handles clicks until the user closes it. Code after it runs only when the window closes.
2. What is wrong with tk.Button(root, text="Go", command=go())?
go() runs immediately and its return value (usually None) becomes the command. Write command=go.
3. Which layout manager would you use for a login form with labels and boxes side by side?
grid, with the labels in column 0 and the entry boxes in column 1.
4. Write the openpyxl code to put "Total" in cell A10 and save.
ws["A10"] = "Total"
wb.save("report.xlsx")5. How would you update a label every second without freezing the window?
Use root.after(1000, function) inside the function itself, so it schedules its own next run.