What is a GUI and how does Tkinter start?
A GUI (graphical user interface) shows windows, buttons and text boxes. A CLI (command-line interface) only shows text. Tkinter is Python's built-in GUI library, so nothing extra needs installing.
import tkinter as tk
root = tk.Tk() # the main window
root.title("My App") # text in the title bar
root.geometry("400x300") # width x height in pixels
root.mainloop() # show it and wait for eventsmainloop() is the event loop. It keeps the window open and keeps checking: did the user click? type? close? Code after mainloop() runs only when the window closes.
Widgets are objects with properties
Each widget is an object. You create it from a class and give it a parent (the window it lives in) and properties (options).
| Widget | Use |
|---|---|
| Label | shows text or an image |
| Entry | one-line text box; read it with .get() |
| Text | many-line text box |
| Button | runs a function when clicked (command=) |
| Checkbutton | yes/no tick box, linked to an IntVar/BooleanVar |
| Radiobutton | choose one of several, all sharing one variable |
| Frame | a box that groups other widgets |
| Canvas | drawing area for shapes, lines and games |
Common properties: text, bg (background colour), fg (text colour), font, width. Change them later with widget.config(bg="yellow").
Messages: from tkinter import messagebox, then messagebox.showinfo("Title", "Saved!"), showwarning, showerror or askyesno (returns True/False).
Layout: pack, grid and place
A widget is invisible until a layout manager places it.
pack(): stacks widgets top to bottom (orside="left"). Quick and simple.grid(row=r, column=c): a table of rows and columns. Best for forms.place(x=…, y=…): exact pixel position. Precise but does not adapt when the window resizes.
Do not mix pack and grid inside the same parent; use a Frame for each part instead.
Events, handlers and a small game
A GUI program is event-driven: it does not run top to bottom and stop. It waits for events (click, key press, mouse move) and runs a handler function for each.
def say_hi():
name = ent.get()
lab.config(text="Hello, " + name + "!")
btn = tk.Button(root, text="Say hi", command=say_hi)Note: command=say_hi without brackets. With brackets the function would run at once, not on click.
For keys use bind; the handler receives an event object:
cv = tk.Canvas(root, width=400, height=300, bg="black")
ball = cv.create_oval(10, 10, 40, 40, fill="orange")
def right(event):
cv.move(ball, 20, 0)
root.bind("<Right>", right)A game adds a score variable, checks if two shapes overlap (with cv.coords), and uses root.after(ms, function) to move things on a timer.
Try it yourself
Type the say_hi program above into a .py file and run it. Then: (1) change the button colour with bg; (2) add a Checkbutton for 'Loud' that shows the greeting in capitals with .upper(); (3) switch from pack to grid and see the form line up.
Key formulas and definitions
- root = tk.Tk() … root.mainloop()
- w = tk.Widget(parent, option=value)
- w.pack() | w.grid(row=r, column=c) | w.place(x=, y=)
- w.config(option=value) — change a property
- entry.get() — read the text
- tk.Button(root, command=function_name) — no brackets
- root.bind("<Key>", handler) — handler(event)
- messagebox.showinfo(title, message)
Worked examples
1. Make a window titled 'Quiz' with a label 'Ready?'.
import tkinter as tk root = tk.Tk() root.title('Quiz') tk.Label(root, text='Ready?').pack() root.mainloop()
2. Add an Entry and a Button that shows the typed name in a message box.
from tkinter import messagebox ent = tk.Entry(root); ent.pack() def show(): messagebox.showinfo('Hi', 'Hello ' + ent.get()) tk.Button(root, text='OK', command=show).pack()
3. Lay out a login form: labels in column 0, entries in column 1.
tk.Label(root, text='User').grid(row=0, column=0) tk.Entry(root).grid(row=0, column=1) tk.Label(root, text='PIN').grid(row=1, column=0) tk.Entry(root, show='*').grid(row=1, column=1)
4. A Checkbutton 'Dark mode' should turn the window background black when ticked.
dark = tk.IntVar() def toggle(): root.config(bg='black' if dark.get() == 1 else 'white') tk.Checkbutton(root, text='Dark mode', variable=dark, command=toggle).pack()
5. Three Radiobuttons choose Easy / Medium / Hard. Print the choice on a button click.
level = tk.StringVar(value='Easy') for t in ['Easy', 'Medium', 'Hard']: tk.Radiobutton(root, text=t, value=t, variable=level).pack() tk.Button(root, text='Start', command=lambda: print(level.get())).pack()
6. Move a Canvas square left and right with the arrow keys.
sq = cv.create_rectangle(180, 130, 220, 170, fill='blue') root.bind('<Left>', lambda e: cv.move(sq, -10, 0)) root.bind('<Right>', lambda e: cv.move(sq, 10, 0))
Common mistakes
- Writing command=say_hi() with brackets: the function runs once at start and the button then does nothing.
- Forgetting pack/grid/place, so the widget never appears.
- Forgetting root.mainloop(), so the window flashes and closes (or never shows).
- Mixing pack() and grid() in the same parent, which can freeze the program.