Environment Check: Python Installation and Importing Tkinter
Tkinter is the standard GUI toolkit that ships with most Python installations. Before building a window, verify two things: (1) you can run Python, and (2) you can import tkinter without errors.
Verify Python is available
In a terminal (Command Prompt/PowerShell on Windows, Terminal on macOS/Linux), run:
python --versionIf that fails, try:
python3 --versionVerify Tkinter import
Create a file named check_tkinter.py and run it:
import tkinter as tk
print("Tkinter imported successfully:", tk.TkVersion)If you see a version number printed, you are ready. If you get an import error, your Python installation may not include Tk support (common on some Linux setups). In that case, install the OS package that provides Tk for Python, then re-run the check.
Continue in our app.
You can listen to the audiobook with the screen off, receive a free certificate for this course, and also have access to 5,000 other free online courses.
Or continue reading below...Download the app
Creating the Root Window (Your App’s Main Window)
Every Tkinter app starts by creating a root window. This root object is the top-level container for everything you will place in your GUI (buttons, labels, frames, etc.).
Minimal app:
import tkinter as tk
root = tk.Tk() # create the main window
root.mainloop() # start the event loopTwo key ideas are introduced here:
tk.Tk()creates the window and initializes Tk.mainloop()starts the event loop, which keeps the window responsive (handling redraws, clicks, key presses, and window manager events).
Setting Window Properties: Title, Size, and Icon
After creating root and before calling mainloop(), you typically configure window properties. Many of these settings can also be changed while the app is running, but it’s common to set them up front.
Set the window title
import tkinter as tk
root = tk.Tk()
root.title("My First Tkinter App")
root.mainloop()The title is what you see in the window’s title bar (as controlled by the operating system’s window manager).
Set the initial window size (and position)
Tkinter uses a geometry string: "WIDTHxHEIGHT". You can optionally add position: "WIDTHxHEIGHT+X+Y".
import tkinter as tk
root = tk.Tk()
root.title("Sized Window")
root.geometry("500x300") # width=500, height=300
root.mainloop()Example with position:
root.geometry("500x300+200+100") # place window at x=200, y=100Notes:
- Initial size is applied when the window is first shown.
- Changing geometry later (while running) resizes/moves the window immediately.
Set a window icon
Icons are OS-dependent. The most common approach on Windows is using an .ico file with iconbitmap. On other platforms, support varies.
import tkinter as tk
from pathlib import Path
root = tk.Tk()
root.title("Window with Icon")
icon_path = Path("assets") / "app.ico"
if icon_path.exists():
root.iconbitmap(str(icon_path))
root.mainloop()Practical tips:
- Use an absolute path or build paths with
pathlibto avoid “file not found” issues when running from different working directories. - Keep icons in a dedicated folder (for example,
assets/) so they’re easy to locate and package later.
Running mainloop(): The Event Loop That Keeps the App Alive
root.mainloop() starts Tkinter’s event loop. Without it, the script would finish immediately and the window would appear briefly (or not at all). With it, Tkinter waits for events (mouse, keyboard, window close) and dispatches them to your GUI.
A typical “minimal but practical” starter template looks like this:
import tkinter as tk
from pathlib import Path
root = tk.Tk()
root.title("Starter App")
root.geometry("500x300")
icon_path = Path("assets") / "app.ico"
if icon_path.exists():
root.iconbitmap(str(icon_path))
root.mainloop()Guided Exercise: Modify Window Properties and Observe When Changes Apply
This exercise helps you see which changes are applied immediately while the app is running versus which are mainly “startup configuration.” You will run one script and interact with it.
Step 1: Create the exercise script
Create exercise_window_props.py:
import tkinter as tk
root = tk.Tk()
root.title("Exercise: Window Properties")
root.geometry("420x220")
info = tk.Label(
root,
text=(
"Watch what changes immediately vs at startup.\n"
"1) Click 'Change Title'\n"
"2) Click 'Resize Now'\n"
"3) Close and re-run after editing geometry/title"
),
justify="left"
)
info.pack(padx=12, pady=12)
btn_title = tk.Button(root, text="Change Title", command=lambda: root.title("Title Changed While Running"))
btn_title.pack(pady=4)
btn_resize = tk.Button(root, text="Resize Now", command=lambda: root.geometry("600x350"))
btn_resize.pack(pady=4)
root.mainloop()Step 2: Run it and observe “immediate” changes
When you click:
- Change Title: the title bar updates immediately because
root.title(...)can be applied at runtime. - Resize Now: the window resizes immediately because
root.geometry(...)can be applied at runtime.
Step 3: Observe “startup” changes by editing and re-running
Now close the window, edit these lines near the top:
root.title("Exercise: Window Properties")
root.geometry("420x220")Change them to something else (for example, a different title and a different initial size), save, and run again. These edits affect what you see when the window first appears (startup configuration). The key difference is not that these settings cannot be changed later, but that you are applying them before the event loop starts, so they define the initial appearance.
If you also add an icon line before mainloop(), you will typically see the icon applied when the window is created/shown. Depending on OS behavior, icon updates may not always be as consistently “live” as title/geometry changes, so it’s best treated as a startup configuration step.
Checklist: Clean Project Folder Layout for Tkinter GUI Projects
project/(root folder)project/main.py(entry point that createsTk()and callsmainloop())project/ui/(GUI code: windows, frames, widget layout)project/assets/(icons, images; keep filenames stable for packaging)project/tests/(optional: tests for non-GUI logic)project/README.md(how to run the app, dependencies, notes)project/.gitignore(ignore caches like__pycache__/and local environment folders)