Questions or a demo for your school?Student? Sit a test
BrainBit Infotech TeachingStart free

Python notes · Topic 21 of 22 · 4 min read

Python GUI apps with Tkinter and office automation

Python Tkinter notes: windows, widgets and layouts, buttons that calculate, after() timers, plus Excel automation with openpyxl and Pillow.

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

WidgetWhat it is
Labeltext or an image the user cannot edit
Entrya one-line text box
Buttona button that runs a function when clicked
Texta multi-line text box
Checkbutton / Radiobuttontick boxes and one-of-many options
Listboxa list to choose from
messageboxpop-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=calculate passes 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 with pack() or grid(); mainloop() runs it.
  • Buttons take command=function without brackets; entry.get() reads input.
  • after() schedules work without freezing the window.
  • openpyxl, Pillow and pathlib automate 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.