Cookbook

GUI Commands & Widget Reference

The vocabulary of GUI programming β€” widgets, geometry, events, variables, dialogs and menus β€” explained conceptually and shown in code. Examples use Tkinter (the universal baseline); the ideas map directly onto every toolkit.

Core Widgets

A widget is any interactive or display element. Conceptually they fall into a few families. Below are the most common Tkinter widgets and their cross-toolkit equivalents.

WidgetPurposeTkinter classQt equivalent
LabelShow static text/imagettk.LabelQLabel
ButtonTrigger an actionttk.ButtonQPushButton
EntrySingle-line text inputttk.EntryQLineEdit
TextMulti-line text areatk.TextQTextEdit
CheckbuttonBoolean on/offttk.CheckbuttonQCheckBox
RadiobuttonOne-of-many choicettk.RadiobuttonQRadioButton
ComboboxDropdown selectionttk.ComboboxQComboBox
ListboxScrollable listtk.ListboxQListWidget
Slider/ScalePick a numeric rangettk.ScaleQSlider
ProgressbarShow progressttk.ProgressbarQProgressBar
Treeview/TableTabular / tree datattk.TreeviewQTreeView
FrameGroup / containerttk.FrameQFrame
CanvasFree-form drawingtk.CanvasQGraphicsView

Creating widgets β€” the universal pattern

In Tkinter every widget takes its parent as the first argument, followed by configuration options as keyword arguments:

python
widget = ttk.Button(
    parent,                       # where it lives in the widget tree
    text="Save",                  # option: visible text
    width=12,                     # option: width in characters
    command=save_file,            # option: callback on click
)

Geometry Managers (Layout Commands)

A widget exists once created, but it is invisible until a geometry manager places it. Tkinter offers three. Never mix them within the same parent container.

pack() β€” stack in a direction

python
w.pack(side="top",      # top | bottom | left | right
       fill="x",        # none | x | y | both β€” stretch to fill
       expand=True,     # claim extra space when window grows
       padx=8, pady=4)  # outer padding in pixels

grid() β€” rows and columns

python
w.grid(row=0, column=1,
       columnspan=2,        # span multiple columns
       sticky="ew",           # n/s/e/w β€” which edges to cling to
       padx=4, pady=4)

# Make a column/row stretch when the window resizes:
parent.columnconfigure(1, weight=1)
parent.rowconfigure(0, weight=1)

place() β€” absolute / relative coordinates

python
w.place(x=20, y=30)                 # exact pixels
w.place(relx=0.5, rely=0.5,        # 50% across / down
        anchor="center")             # center the widget on that point
Rule of thumb

Use grid() for forms, pack() for simple toolbars/stacks, and place() only for special overlays. grid + weight is the key to resizable, professional layouts.


Events & Binding

Interactivity comes from connecting events (something the user did) to callbacks (a function you wrote). There are two mechanisms:

1 Β· The command option (high level)

python
ttk.Button(root, text="Go", command=on_go)
# pass arguments with a lambda:
ttk.Button(root, text="Delete", command=lambda: delete(item_id))

2 Β· bind() (any event)

python
def on_key(event):
    print("key:", event.keysym, "at", event.x, event.y)

root.bind("<Return>",        on_key)   # Enter key
root.bind("<Button-1>",      on_key)   # left mouse click
root.bind("<KeyPress>",      on_key)   # any key
root.bind("<Control-s>",     on_key)   # Ctrl+S
root.bind("<Motion>",        on_key)   # mouse moved
Event patternFires when…
<Button-1/2/3>Left / middle / right mouse pressed
<Double-Button-1>Double left-click
<Return> / <Escape>Enter / Esc key
<KeyPress-a>The "a" key is pressed
<Control-c>Ctrl+C combination
<Enter> / <Leave>Pointer enters / leaves a widget (hover)
<Configure>Widget is resized or moved
Signals & slots (Qt)

Qt expresses the same idea differently: button.clicked.connect(handler). Every widget exposes named signals you connect to slots (handlers). The concept β€” "event β†’ handler" β€” is identical.


Control Variables (Two-Way Binding)

Tkinter offers special variable objects that stay synchronised with a widget. Read the variable to get the current value; set it to update the widget β€” no manual refresh needed.

python
name   = tk.StringVar(value="Ada")
agree  = tk.BooleanVar()
volume = tk.IntVar(value=50)

ttk.Entry(root, textvariable=name).pack()
ttk.Checkbutton(root, text="I agree", variable=agree).pack()
ttk.Scale(root, from_=0, to=100, variable=volume).pack()

print(name.get(), agree.get(), volume.get())   # read
name.set("Grace")                              # write β†’ entry updates

# React whenever the value changes:
name.trace_add("write", lambda *_: print("now:", name.get()))

Configuring & Querying Widgets

After creation you can change options at runtime with config() (alias configure()) and read them by indexing:

python
btn = ttk.Button(root, text="On")
btn.config(text="Off", state="disabled")   # change options
current = btn["text"]                          # read an option

label.config(foreground="white", background="#3776ab")
entry.delete(0, "end")                          # clear an Entry
entry.insert(0, "default text")

Standard Dialogs

Toolkits ship ready-made dialogs for common interactions so you don't rebuild them.

python
from tkinter import messagebox, filedialog, simpledialog, colorchooser

messagebox.showinfo("Done", "File saved.")
ok = messagebox.askyesno("Quit", "Exit without saving?")

path  = filedialog.askopenfilename(filetypes=[("Text", "*.txt")])
save  = filedialog.asksaveasfilename(defaultextension=".txt")
folder = filedialog.askdirectory()

age   = simpledialog.askinteger("Age", "How old are you?")
color = colorchooser.askcolor()

python
menubar = tk.Menu(root)
root.config(menu=menubar)

file_menu = tk.Menu(menubar, tearoff=0)
file_menu.add_command(label="New",  accelerator="Ctrl+N", command=new_file)
file_menu.add_command(label="Open", command=open_file)
file_menu.add_separator()
file_menu.add_command(label="Exit", command=root.quit)
menubar.add_cascade(label="File", menu=file_menu)

root.bind("<Control-n>", lambda e: new_file())   # wire the accelerator

Canvas Drawing

The Canvas is a free-form surface for shapes, images, lines and custom graphics β€” the basis for charts, diagrams and simple games.

python
c = tk.Canvas(root, width=300, height=200, background="white")
c.pack()
c.create_line(10, 10, 290, 10, fill="blue", width=3)
c.create_rectangle(20, 40, 120, 100, fill="#ffd43b")
c.create_oval(150, 40, 250, 120, outline="red")
item = c.create_text(150, 160, text="Hello", font=("Segoe UI", 16))
c.move(item, 0, -5)            # shift an existing item

Timers & Keeping the UI Responsive

Use after() to schedule work on the event loop without blocking it β€” ideal for clocks, animations and polling background results.

python
import time

def tick():
    clock.config(text=time.strftime("%H:%M:%S"))
    root.after(1000, tick)      # re-run in 1000 ms

clock = ttk.Label(root, font=("Segoe UI", 24))
clock.pack(padx=20, pady=20)
tick()                          # start the loop
root.mainloop()
βœ— Anti-pattern

Calling time.sleep(5) inside a callback freezes the whole window for 5 seconds. Use after() for delays, and threads for heavy work (see Best Practices β†’ Threading).


One-Page Cheat Sheet

TaskCommand (Tkinter)
Create windowroot = tk.Tk()
Title / sizeroot.title("X"); root.geometry("400x300")
Start approot.mainloop()
Add labelttk.Label(root, text="Hi").pack()
Button + actionttk.Button(root, text="Go", command=fn)
Read text inputentry.get()
Layout: stackw.pack(side="top", fill="x")
Layout: tablew.grid(row=0, column=1)
Bind eventroot.bind("<Return>", handler)
Change optionw.config(text="New")
Timerroot.after(1000, fn)
Message boxmessagebox.showinfo("T", "msg")
Close windowroot.destroy()