Python Tkinter
Tutorial 57 of 65 · pythondeck.com Python course
Tkinter is Python's built-in GUI toolkit, a wrapper around Tk. Lightweight, cross-platform and dependency-free. Great for quick utilities, internal tools and learning GUI concepts. For visual layout use a Tkinter GUI Designer.
Tkinter ships with Python—no extra install—for desktop utilities, teaching GUIs, and quick internal tools on Windows, macOS, and Linux.
The widget toolkit is dated visually but dependable for forms, file pickers, and matplotlib embeds.
For teams forbidden from adding heavy dependencies, tkinter remains the zero-footprint way to give CLI scripts a face.
Root window — Tk(), mainloop event pump.
Widgets — Frame, Label, Button, Entry, Listbox, Canvas.
Geometry managers — pack, grid (prefer grid for complex layouts), place.
Events — command callbacks; bind for keys and mouse.
ttk — themed widgets matching OS appearance better than classic Tk.
Dialogs — filedialog, messagebox for standard UX.
Tk is single-threaded: long work in callbacks freezes UI—use threading or queue to worker and poll with after(). For richer UIs consider CustomTkinter or migrating to Qt/Flet. Still, tkinter excels at 200-line admin scripts shipping with CPython.
Internationalization and high-DPI require platform tweaks; test on target OS if distributing binaries (pyinstaller).
Treeview and Notebook widgets support master-detail UIs without leaving the standard library.
Menu bars and accelerator keys feel native on each OS when you test shortcuts on Windows and macOS separately.
Blocking the main thread with network or disk work.
Mixing pack and grid in the same parent causing layout fights.
Creating widgets in loops without storing references, garbage-collected UI.
Expecting modern mobile-style animations without extra libraries.
Subclass Frame for reusable panels; separate UI from business logic.
Use ttk and consistent padding (padx/pady) for readable forms.
Validate input before closing dialogs; disable buttons during work.
Package with pyinstaller only after testing on a clean VM.
Bind Return key and accelerators consistently; document keyboard shortcuts in Help menu.
Re-read the examples below with these ideas in mind; change variable names and inputs to match your own project.
The program below demonstrates hello window. Read the comments on each line, run the code, then change names or values to see how the output shifts.
# Example: Hello window
# Run in the REPL or save as a .py file and execute with python.
import tkinter as tk
root = tk.Tk()
root.title("PythonDeck")
tk.Label(root, text="Hello Tkinter", font=("Arial", 16)).pack(padx=20, pady=20)
root.mainloop()
This sample walks through button + entry in a small, runnable script. Paste it into the REPL or save it as a .py file before you continue to the next block.
# Example: Button + entry
# Run in the REPL or save as a .py file and execute with python.
import tkinter as tk
def on_click():
print("You typed:", entry.get())
root = tk.Tk()
entry = tk.Entry(root, width=30)
entry.pack(pady=5)
tk.Button(root, text="Submit", command=on_click).pack()
root.mainloop()
Here is a hands-on illustration of ttk widgets. Follow the inline comments first; only then execute the snippet and compare the result with what you expected.
# Example: ttk widgets
# Run in the REPL or save as a .py file and execute with python.
import tkinter as tk
from tkinter import ttk
root = tk.Tk()
ttk.Label(root, text="Name:").grid(row=0, column=0)
ttk.Entry(root).grid(row=0, column=1)
ttk.Button(root, text="OK").grid(row=1, columnspan=2, pady=8)
root.mainloop()
The program below demonstrates button callback. Read the comments on each line, run the code, then change names or values to see how the output shifts.
# Tkinter builds desktop UIs with widgets + mainloop
import tkinter as tk # GUI toolkit
root = tk.Tk() # main window
root.title("Counter") # window title
label = tk.Label(root, text="0") # status label
label.pack(pady=8) # vertical layout
count = 0 # mutable state
def inc(): # button handler
global count # modify module-level counter
count += 1 # increment
label.config(text=str(count)) # refresh label
tk.Button(root, text="+1", command=inc).pack() # wire callback
# root.mainloop() # uncomment to open window
print("tkinter demo ready") # non-interactive confirmation
This sample walks through entry binding in a small, runnable script. Paste it into the REPL or save it as a .py file before you continue to the next block.
# Entry widgets capture text; bind Return key
import tkinter as tk # tkinter
root = tk.Tk() # window
entry = tk.Entry(root) # text box
entry.pack(padx=10, pady=10) # placement
output = tk.Label(root, text="") # mirror label
output.pack() # below entry
def on_enter(event=None): # Enter key handler
output.config(text=entry.get()) # copy text
entry.bind("<Return>", on_enter) # keyboard binding
# root.mainloop() # GUI loop
print("binding configured") # script-friendly
Continue with these focused follow-up lessons on Python Tkinter: