How to Make a GUI in Python

What you’ll build or solve

You’ll build a small Tkinter app with a window, a label, a button, and a text input.

When this approach works best

This approach works best when you:

  • Want a simple desktop UI for a personal tool, like a small tracker or converter.
  • Need a quick interface for a script so you stop editing values in code.
  • Learn GUI basics using the standard library without installing extra packages.

Avoid this approach when:

  • You need a modern-looking UI or complex layout and styling. Tkinter can do a lot, but it has limits.

Prerequisites

  • Python 3 installed
  • You know what variables are
  • You can run a .py file from the terminal or your editor

Step-by-step instructions

1) Create a window and start the event loop

Tkinter apps have a main window and an event loop that keeps the UI responsive.

import tkinter as tk

root = tk.Tk()
root.title("My Tkinter App")
root.geometry("320x160")

root.mainloop()

What to look for:

root.mainloop() must be the last line. If you skip it, the window opens and closes immediately.


2) Add a label and a button

Widgets are UI elements like labels and buttons. You create them, then place them in the window.

import tkinter as tk

root = tk.Tk()
root.title("My Tkinter App")
root.geometry("320x160")

label = tk.Label(root, text="Hello!")
label.pack(pady=10)

button = tk.Button(root, text="Click me")
button.pack()

root.mainloop()

3) Handle button clicks with a command function

To react to a click, pass a function to command. Tkinter calls it when the user clicks the button.

import tkinter as tk

root = tk.Tk()
root.title("Counter")
root.geometry("320x160")

label = tk.Label(root, text="Clicks: 0")
label.pack(pady=10)

count = 0

def on_click() -> None:
    global count
    count += 1
    label.config(text=f"Clicks: {count}")

button = tk.Button(root, text="Click me", command=on_click)
button.pack()

root.mainloop()

What to look for:

Pass the function name (command=on_click), not a call (command=on_click()).


4) Add text input and read it

Use Entry for a single-line text box. Call .get() to read what the user typed.

import tkinter as tk

root = tk.Tk()
root.title("Input Demo")
root.geometry("320x160")

entry = tk.Entry(root, width=25)
entry.pack(pady=10)

label = tk.Label(root, text="Type something and click Show")
label.pack(pady=10)

def show_text() -> None:
    text = entry.get()
    label.config(text=text)

button = tk.Button(root, text="Show", command=show_text)
button.pack()

root.mainloop()

Examples you can copy

1) Tiny “hello” window

import tkinter as tk

root = tk.Tk()
root.title("Hello")
root.geometry("320x160")

tk.Label(root, text="Hello, world!").pack(pady=30)

root.mainloop()

2) Simple number doubler

This stays focused on the UI pattern. It assumes the input is a valid number.

import tkinter as tk

root = tk.Tk()
root.title("Doubler")
root.geometry("320x160")

label = tk.Label(root, text="Enter a number, then click Double")
label.pack(pady=10)

entry = tk.Entry(root, width=20)
entry.pack()

def double() -> None:
    n = float(entry.get())
    label.config(text=f"Result: {n * 2}")

tk.Button(root, text="Double", command=double).pack(pady=10)

root.mainloop()

3) Complete greeter app (label + input + button)

import tkinter as tk

root = tk.Tk()
root.title("Greeter")
root.geometry("320x160")

label = tk.Label(root, text="Type your name and click Greet")
label.pack(pady=10)

entry = tk.Entry(root, width=25)
entry.pack()

def greet() -> None:
    name = entry.get().strip()
    if name:
        label.config(text=f"Hi, {name}!")
    else:
        label.config(text="Please type a name.")

tk.Button(root, text="Greet", command=greet).pack(pady=10)

root.mainloop()

Common mistakes and how to fix them

Mistake 1: The window opens and closes immediately

You create the window but forget the event loop:

import tkinter as tk

root = tk.Tk()
root.title("Oops")

Why it breaks:

Without mainloop(), Python finishes the script and the window closes.

Correct approach:

import tkinter as tk

root = tk.Tk()
root.title("Fixed")
root.mainloop()

Mistake 2: The button click runs too early

You might write:

button = tk.Button(root, text="Click", command=greet())

Why it breaks:

greet() runs immediately and its return value becomes the command.

Correct approach:

button = tk.Button(root, text="Click", command=greet)

Mistake 3: Getting a ValueError when converting input

You might write:

n = float(entry.get())

Why it breaks:

If the input is empty or not a number, float() raises ValueError.

Correct approach (simple guard):

raw = entry.get().strip()
if raw:
    n = float(raw)
    label.config(text=f"Result: {n * 2}")
else:
    label.config(text="Enter a number first")

Troubleshooting

If you see ModuleNotFoundError: No module named 'tkinter', your Python build may not include Tk support. Install the Tk package for your system (often named python3-tk on Linux), then try again.

If clicks do nothing, confirm you passed command=my_function and defined the function before creating the button.

If your label does not change, use label.config(text="...") and make sure you update the same label variable.

If you get NameError inside the click handler, check that the widget variable (entry, label) exists where your function can access it.


Quick recap

  • Create a window with tk.Tk() and keep it open with root.mainloop().
  • Add widgets like Label, Button, and Entry, then place them with pack().
  • Handle clicks by passing a function to command.
  • Read text input with entry.get() and update the UI with label.config(text="...").