Learn
08.1 | TKINTER: WINDOWS, WIDGETS AND LAYOUTS
01 | FROM A PROMPT TO A WINDOW
A console program often asks a question and waits at input(). A graphical user interface, or GUI, gives the user visible controls: text fields, buttons and lists. The user chooses an action rather than following only one fixed prompt sequence.
Tkinter is Python’s interface to the Tk GUI toolkit. ttk provides themed widgets that fit the operating system more naturally. A widget is one interface component, such as a label or button. Widgets are Python objects with configuration and behaviour.
The interface runs as a desktop Python program. Putting this source in a web page does not turn it into a browser app. The small browser illustrations on these lessons explain ideas; run actual Tkinter code in your editor.
02 | CHECK YOUR INSTALLATION FIRST
Tkinter belongs to Python’s standard interface libraries but the Tk support is optional in some distributions. Run the diagnostic below through the interpreter you intend to use. A small demonstration window should open.
If the module or display support is missing, use your Python distributor’s installation instructions or school support process. Do not assume pip install tkinter is the right fix. A virtual environment does not create missing operating-system GUI libraries.
The examples require a desktop session with a display. An SSH terminal or headless server can import some components without being able to show a window. Test locally on the student computer before debugging a window that cannot be displayed.
TERMINAL | SELECTED PROJECT INTERPRETER
python -m tkinter
03 | YOUR FIRST COMPLETE WINDOW
tk.Tk() creates the main root window. title supplies the text shown in its title bar. minsize sets a minimum width and height in pixels; it does not say every control must be that exact size.
The frame groups the label and close button. pack places widgets in their parent. Creating a widget without placing it through a geometry manager does not normally make it appear.
root.mainloop() starts event processing and keeps the interface responsive until it closes. command=root.destroy passes the callable close operation. Writing root.destroy() there would call it immediately during setup.
import tkinter as tk
from tkinter import ttk
root = tk.Tk()
root.title("My first desktop app")
root.minsize(360, 180)
frame = ttk.Frame(root, padding=16)
frame.pack(fill="both", expand=True)
ttk.Label(frame, text="Hello, future developer!").pack(pady=12)
ttk.Button(frame, text="Close", command=root.destroy).pack(pady=8)
root.mainloop()04 | PARENTS EXPLAIN WHERE WIDGETS BELONG
The first argument in ttk.Label(frame, ...) is its parent. The label belongs inside frame, and frame belongs inside root. This hierarchy tells Tk where to manage the widget’s layout and lifetime.
A frame is a container. It can separate a form, a task list and an action bar into manageable areas. Each frame can have its own layout rules instead of forcing every control into one complicated grid.
Destroying a parent also destroys its child widgets. Use one Tk root for these applications; if you later need another independent window within the same application, consider Toplevel rather than starting an unrelated second Tk interpreter.
05 | CHOOSE THE CONTROL FOR THE JOB
A Label displays information. An Entry collects a single line of text. A Button requests an action. A readonly Combobox offers a fixed set of choices. A Treeview displays structured rows, making it useful for the study planner.
StringVar is a Tkinter-linked value that widgets can read through textvariable. Use its get() and set() methods to retrieve or change the text. It is not the same as a normal Python string, and an Entry still supplies text even when the user types digits.
Prefer clear labels and units such as “Planned minutes” rather than an unexplained empty box. Give feedback near the task so the user knows whether it was accepted. A good interface reduces guessing.
| Widget | Example use | Important distinction |
|---|---|---|
| ttk.Label | Display task feedback | Displaying text does not validate input |
| ttk.Entry | Enter subject or task | Its content is text |
| ttk.Button | Add a task | command receives a callable |
| ttk.Combobox | Choose open/completed/all | readonly limits typed options |
| ttk.Treeview | Display saved task rows | Row position is not record identity |
06 | ARRANGE A FORM WITH GRID
grid places widgets in numbered rows and columns starting at zero. In this form, labels belong in column zero and inputs in column one. Using the same columns aligns controls without manually measuring every pixel.
sticky describes which cell edges a widget follows: w aligns to the west edge, ew stretches east to west, and nsew fills in both directions. padx and pady add spacing outside a widget; the frame’s padding gives the whole group breathing room.
columnconfigure(1, weight=1) allows the input column to receive extra width. The root’s configured column lets the frame receive that extra width first. Resizing works through the hierarchy, not through a single magic setting on the Entry.
import tkinter as tk
from tkinter import ttk
root = tk.Tk()
root.title("Study task form")
root.columnconfigure(0, weight=1)
frame = ttk.Frame(root, padding=16)
frame.grid(row=0, column=0, sticky="nsew")
frame.columnconfigure(1, weight=1)
subject = tk.StringVar(root)
task = tk.StringVar(root)
ttk.Label(frame, text="Subject:").grid(row=0, column=0, sticky="w", padx=(0, 12), pady=6)
ttk.Entry(frame, textvariable=subject).grid(row=0, column=1, sticky="ew", pady=6)
ttk.Label(frame, text="Task:").grid(row=1, column=0, sticky="w", padx=(0, 12), pady=6)
ttk.Entry(frame, textvariable=task).grid(row=1, column=1, sticky="ew", pady=6)
ttk.Button(frame, text="Close", command=root.destroy).grid(row=2, column=1, sticky="e", pady=10)
root.mainloop()07 | PACK, GRID AND PLACE
pack is convenient for a vertical stack or simple bars. grid is convenient for aligned forms and structured panels. place positions with explicit or relative coordinates and can suit overlays, but hand-positioning every ordinary form control often makes resizing harder.
Do not use pack and grid to manage sibling widgets inside the same parent. You may pack a frame into root and grid its children inside that frame, because these are different containers.
Keep references when you will change a widget later. entry = ttk.Entry(...) followed by entry.grid(...) retains the widget. entry = ttk.Entry(...).grid(...) assigns the grid method’s result, usually None, so entry is no longer your widget.
08 | EXPLORE THE RESIZING RULE
This browser model shows a grid form with either a growing input column or a fixed-width input column. It illustrates space distribution rather than reproducing native Tk appearance. Try the wider window setting.
09 | DESIGN FOR THE USER, NOT YOUR SCREEN
Resize your window and check long labels, keyboard focus and text visibility. Native fonts, display scaling and theme sizes vary between machines. Avoid promising that one exact screenshot will match every operating system.
Use the Tab key to move between controls and Enter where an action is appropriate. Keep controls in a logical creation and visual order. Leave space around input labels and separate actions with clear wording.
A ttk theme can affect how styles appear. Learn the layout and behaviour first, then customise selected appearance settings deliberately rather than replacing every native usability convention.
10 | BUILD ONE SMALL FORM
Create a subject and task form with a close button. Save it as a complete .py file and run it with the selected interpreter. At this point it displays fields but does not save their contents. That limit is intentional: layout and persistence are separate responsibilities.
Explain each widget’s parent and why the input column expands. Then remove one column weight, rerun and observe the result. This kind of controlled change gives stronger understanding than copying a finished interface without testing its layout.
OFFICIAL REFERENCE
Use the worked examples first, then consult the official documentation to check widget, input or drawing options. Match it to the version selected in your project environment.
PUT YOUR SKILLS TO WORK
Use the Section 8 challenges to practise these ideas independently. Work in your Python editor, predict results and keep a short test record.
Section 8 challenges Python course navigation