Get AI summaries of any video or article — Sign up free
Python Tkinter Tutorial (Part 1): Getting Started, Elements, Layouts, and Events thumbnail

Python Tkinter Tutorial (Part 1): Getting Started, Elements, Layouts, and Events

Corey Schafer·
5 min read

Based on Corey Schafer's video on YouTube. If you like this content, support the original creators by watching, liking and subscribing to their content.

TL;DR

Tkinter GUIs require `root.mainloop()` to keep the window open and process user events.

Briefing

Tkinter’s core workflow—create a root window, add widgets, lay them out with a geometry manager, and wire user actions through callbacks and event bindings—gets a practical walkthrough that ends with a small but functional form. The payoff is a working pattern for building GUI apps in Python without extra dependencies, plus a clear path for making layouts resize cleanly and behave predictably when users click buttons or press keys.

The tutorial starts by positioning Tkinter as part of Python’s standard library, then immediately flags a real-world setup wrinkle: on a Homebrew-managed Python install for macOS, Tkinter components may be missing, requiring an additional install via Homebrew. After that, a quick Tkinter test (`tk._test()`) confirms the environment by popping up a window that reports the Tkinter version and offers basic controls.

From there, the first “real” app follows a minimal but essential structure: initialize the main window (`root = tk.Tk()`), set a title (`root.title(...)`), and keep the interface alive with `root.mainloop()`. Without the main loop, the window opens and closes too quickly to interact with.

Widgets then enter the scene in a deliberate sequence. A button is created with `tk.Button`, attached to a parent (the root window at first), and placed using `grid`. The tutorial emphasizes a common mistake: creating a widget isn’t enough—each one must be added to the window via a geometry manager. A label is added the same way, and the layout is controlled by specifying `row` and `column` indices (zero-based). This establishes the mental model for grid-based placement.

Interactivity comes next. Clicking a button triggers a Python function through the button’s `command` parameter, with the function passed as a reference (no parentheses). The example evolves from printing to the console to updating the GUI itself by changing a label’s text via `label.config(...)`. To demystify widget options, the tutorial demonstrates inspecting configuration keys by printing `label.config()` results.

The tutorial then builds a simple form: a text entry, an “Add” button, and a list box to display submitted items. A `frame` acts as a container so the widgets can be organized and laid out more cleanly than placing everything directly on the root. The “Add” function reads the entry (`entry.get()`), prevents blank submissions, inserts the text into the list box (`text_list.insert(tk.END, text)`), and clears the entry (`entry.delete(0, tk.END)`). Keyboard support is added with `entry.bind('<Return>', ...)`, along with the important caveat that bound callbacks receive an event object—so the handler must accept it (or use a lambda to adapt it).

Finally, layout polish focuses on responsiveness. Grid weights (`columnconfigure`/`rowconfigure`) and `sticky` settings (`N`, `S`, `E`, `W`) ensure widgets expand and align as the window resizes. The tutorial also shows why frames matter by duplicating the form into a second frame, then controlling how the two columns share space through root column weights. Padding (`padx`, `pady`) improves visual separation, and `ttk` themed widgets are introduced to make controls look more native across platforms (noting that some widgets like `Listbox` lack themed equivalents). The result is a repeatable Tkinter blueprint for forms, events, and responsive layouts—ready to be extended in later parts with classes, multiple windows, file I/O, images, and conditional widget behavior.

Cornell Notes

Tkinter GUI building in Python follows a repeatable loop: create a root window, start `mainloop()`, add widgets, place them with `grid`, and connect user actions to Python functions. The tutorial demonstrates button callbacks via the `command` parameter and keyboard handling via `bind('<Return>', ...)`, including the key detail that bound handlers receive an event argument. A small form (entry + add button + list box) shows how to read user input, validate it, insert items into a list, and clear the entry. Layout quality improves by using `frame` containers, `sticky` alignment, and `rowconfigure`/`columnconfigure` weights so widgets resize predictably. Finally, `ttk` themed widgets are used where available to better match the look of the operating system.

Why does a Tkinter window sometimes appear and immediately close, and what fixes it?

Tkinter windows close instantly if the program doesn’t enter the event loop. After creating the main window with `root = tk.Tk()`, the interface must stay alive using `root.mainloop()`. Without `mainloop()`, the script finishes and the window disappears before a user can interact.

What’s the practical difference between a button’s `command` callback and an event binding like `bind('<Return>', ...)`?

A button uses `command=some_function`, which calls that function when the button is clicked. Event bindings use `widget.bind(event_pattern, callback)`, and the callback is invoked when the event occurs. A key difference: `bind` callbacks automatically receive an event object argument, so the callback must accept it (e.g., `def add_to_list(event=None): ...`) or adapt it with a lambda.

How does `grid` placement work in Tkinter, and what common mistake prevents widgets from showing up?

`grid` positions widgets by `row` and `column` indices (zero-based). Widgets must be explicitly added to the layout manager—creating `tk.Button(...)` or `tk.Label(...)` alone doesn’t display anything. Calling `widget.grid(...)` is what actually places it in the window (or in a parent `frame`).

How does the tutorial make the form responsive when the window is resized?

Responsiveness comes from combining `sticky` and grid weights. `sticky` (like `EW` or `NSEW`) tells widgets which sides to attach to so they stretch appropriately. `root.columnconfigure(index, weight=...)` and `root.rowconfigure(index, weight=...)` control how extra space is distributed. The tutorial also configures the `frame`’s internal grid so the entry and list box expand in the intended directions while the button stays stable.

What role do `frame` containers play beyond organization?

Frames act as nested layout regions with their own grid coordinates. That means widgets inside a frame can be laid out starting at row/column 0 within that frame, avoiding manual “math” to offset positions in the root grid. The tutorial demonstrates this by duplicating the form into a second frame and placing the two frames side-by-side in the root window.

How do `ttk` themed widgets change the look of a Tkinter app?

`ttk` provides themed versions of many widgets that better match the native UI style of the operating system. The tutorial switches from `tk.Frame`, `tk.Entry`, and `tk.Button` to `ttk.Frame`, `ttk.Entry`, and `ttk.Button` (while leaving `Listbox` as `tk.Listbox` because it lacks a themed counterpart). On macOS, the buttons and entry fields visibly adopt a more native appearance.

Review Questions

  1. What specific lines are required to keep a Tkinter window open and responsive to events?
  2. When using `bind('<Return>', ...)`, how should the callback be written to avoid errors caused by the event argument?
  3. How do `sticky` and grid weights work together to control which widgets expand during window resizing?

Key Points

  1. 1

    Tkinter GUIs require `root.mainloop()` to keep the window open and process user events.

  2. 2

    Widgets must be placed with a geometry manager like `grid`; creating a widget object alone won’t display it.

  3. 3

    Button clicks use `command=function_reference`, while key presses use `bind(event_pattern, callback)` and bound callbacks receive an event object.

  4. 4

    A `frame` provides a reusable container with its own grid layout, making complex or duplicated layouts easier to manage.

  5. 5

    Responsive resizing depends on `sticky` alignment plus `rowconfigure`/`columnconfigure` weights to distribute extra space.

  6. 6

    Form logic typically reads input with `entry.get()`, validates it, updates a list box with `insert(tk.END, ...)`, and clears the entry with `delete(0, tk.END)`.

  7. 7

    `ttk` themed widgets can improve cross-platform appearance, but some widgets (like `Listbox`) may not have themed equivalents.

Highlights

Tkinter’s event loop (`mainloop`) is the difference between a usable window and one that flashes open then closes.
`bind('<Return>', ...)` callbacks receive an event argument automatically, so handlers must accept it or adapt it with a lambda.
Using `frame` turns layout into nested grids, eliminating the need to manually offset widget row/column positions in the root window.
Grid responsiveness is controlled by combining `sticky` (e.g., `NSEW`) with `rowconfigure`/`columnconfigure` weights.
Switching to `ttk` widgets where available helps controls look more native on the current operating system.

Topics

  • Tkinter Setup
  • Grid Layout
  • Event Handling
  • Frames and Reuse
  • Responsive GUI
  • ttk Theming

Mentioned