Previous | Tutorial index | Next
In Tkinter, everything is a widget. A widget is a graphical element on the screen—a button, a label, a text box, a frame, or even a menu. Think of widgets as the building blocks of your GUI, just as Lego bricks are the building blocks of a model.
Every widget in Tkinter follows a strict parent–child hierarchy:
tk.Label(root, text="Hi")).Tkinter provides over 20 different widget classes. In this tutorial, we will explore the most essential ones in depth, understand their unique methods and options, and learn how to combine them to build functional interfaces.
To make it easier to remember, we can group widgets into four broad categories:
| Category | Purpose | Widgets |
|---|---|---|
| Display & Simple Input | Show static content or get basic text input. | Label, Button, Entry, Text |
| Selection | Let the user choose from predefined options. | Checkbutton, Radiobutton, Listbox, Scale |
| Containers & Structure | Organise and group other widgets. | Frame, LabelFrame, PanedWindow |
| Advanced & Specialised | Provide drawing, menus, and scrolling. | Canvas, Menu, Scrollbar, Toplevel |
We will now examine each widget from the original table, plus a few extra useful ones.
Label – Displaying Text or Imageslabel = tk.Label(parent, text="Hello", font=("Arial", 14))text – the string to display.image – a PhotoImage or BitmapImage object.compound – combines text and image (LEFT, RIGHT, TOP, BOTTOM, CENTER).font – e.g., ("Helvetica", 12, "bold").fg / bg – foreground (text) colour and background colour.relief – border style (FLAT, RAISED, SUNKEN, GROOVE, RIDGE).wraplength – wraps text after a given number of pixels.justify – LEFT, CENTER, or RIGHT for multi‑line text.anchor – where the text is positioned inside the label (n, s, e, w, center, etc.).config() (to change options), cget() (to get an option value).photo = tk.PhotoImage(file="icon.png")
label = tk.Label(root, text="Welcome!", image=photo, compound=tk.TOP)
label.pack()
Button – Clickable Action Triggerbtn = tk.Button(parent, text="Submit", command=my_function)command – the callback function to run on click.state – NORMAL, DISABLED, or ACTIVE.relief – changes when pressed (default is RAISED).underline – underlines a character (e.g., underline=0 underlines the first letter for keyboard shortcuts)..invoke() – programmatically triggers the button (calls the command)..flash() – briefly flashes the button to draw attention.def greet():
print("Hello!")
btn = tk.Button(root, text="Greet", command=greet, bg="lightblue")
btn.pack()
Entry – Single‑Line Text Inputentry = tk.Entry(parent, width=30)show – masks the text (e.g., "*" for passwords).width – width in characters (not pixels).state – NORMAL or DISABLED (read‑only).textvariable – binds to a StringVar for automatic updates.validate / validatecommand – for input validation (e.g., only digits)..get() – retrieves the current text..insert(index, string) – inserts text at a given position (e.g., entry.insert(0, "Default"))..delete(first, last) – deletes characters (e.g., entry.delete(0, tk.END) clears the field)..icursor(index) – sets the cursor position.entry = tk.Entry(root, width=20, bg="white", fg="black")
entry.insert(0, "Enter your name")
entry.pack()
name = entry.get() # Retrieve later
Text – Multi‑Line Rich Text Areatext = tk.Text(parent, height=10, width=50)height / width – in characters (lines and columns).wrap – WORD, CHAR, or NONE (how lines break).spacing1, spacing2, spacing3 – line spacing.undo – enables undo/redo (True or False)..get(start, end) – e.g., text.get(1.0, tk.END) gets all text. (Index 1.0 = line 1, column 0.).insert(index, string) – e.g., text.insert(tk.END, "Append")..delete(start, end) – deletes a range..tag_config(tag, options) – applies styling to tagged regions (e.g., make certain words bold).text_area = tk.Text(root, height=10, width=40, wrap=tk.WORD)
text_area.insert(tk.END, "This is a multi-line text widget.\nYou can type here.")
text_area.pack()
content = text_area.get(1.0, tk.END)
Checkbutton – On/Off Toggleschk = tk.Checkbutton(parent, text="Accept", variable=my_var)variable – a tk.IntVar, tk.StringVar, or tk.BooleanVar that stores the state.onvalue / offvalue – the values stored when checked/unchecked (default 1 and 0 for IntVar).command – a callback triggered when the state changes..select(), .deselect(), .toggle() – programmatically change state.agree_var = tk.IntVar()
chk = tk.Checkbutton(root, text="I agree to terms", variable=agree_var)
chk.pack()
if agree_var.get() == 1:
print("User agreed")
Radiobutton – Mutually Exclusive Selectionrb = tk.Radiobutton(parent, text="Option 1", variable=my_var, value=1)variable – a shared tk.IntVar or tk.StringVar for all radiobuttons in the group.value – the unique value stored in the variable when this button is selected.command – callback when selection changes.variable belong to the same group.choice = tk.IntVar()
rb1 = tk.Radiobutton(root, text="Small", variable=choice, value=1)
rb2 = tk.Radiobutton(root, text="Medium", variable=choice, value=2)
rb3 = tk.Radiobutton(root, text="Large", variable=choice, value=3)
rb1.pack(); rb2.pack(); rb3.pack()
# choice.get() returns 1, 2, or 3.
Listbox – Scrollable List of Itemslst = tk.Listbox(parent, height=5, selectmode=tk.SINGLE)height – number of visible rows.selectmode – SINGLE, BROWSE, MULTIPLE, or EXTENDED.activestyle – style of the active (focused) item..insert(index, item) – e.g., listbox.insert(tk.END, "Apple")..delete(index) – removes an item..get(index) – retrieves an item..curselection() – returns a tuple of selected indices..size() – returns the number of items.listbox = tk.Listbox(root, height=4)
for fruit in ["Apple", "Banana", "Cherry", "Date"]:
listbox.insert(tk.END, fruit)
listbox.pack()
selected = listbox.curselection() # e.g., (2,)
Scale – Slider for Numeric Inputscale = tk.Scale(parent, from_=0, to=100, orient=tk.HORIZONTAL)from_ / to – the numeric range (note the trailing underscore because from is a Python keyword).orient – tk.HORIZONTAL or tk.VERTICAL.resolution – step size (e.g., 0.5).length – length of the slider in pixels.variable – bound to an IntVar or DoubleVar.command – callback function that receives the current value..get() and .set(value).def show_volume(val):
print(f"Volume: {val}")
scale = tk.Scale(root, from_=0, to=100, orient=tk.HORIZONTAL,
command=show_volume, length=200)
scale.pack()
Frame – The Ultimate Organiserframe = tk.Frame(parent, bg="lightgrey", relief=tk.RAISED, bd=2)bg / background – background colour.relief – border style.bd / borderwidth – border thickness.width / height – dimensions (though frames usually expand to fit their contents).pack, grid, place) on its children.main_frame = tk.Frame(root, bg="white", relief=tk.GROOVE, bd=2)
main_frame.pack(padx=10, pady=10)
label = tk.Label(main_frame, text="I am inside a frame")
label.pack()
LabelFrame – A Framed Group with a TitleFrame, but it draws a border around itself and displays a caption (like a "group box").lframe = tk.LabelFrame(parent, text="User Details", padx=5, pady=5)group = tk.LabelFrame(root, text="Contact Info", padx=10, pady=10)
group.pack(padx=10, pady=10)
tk.Entry(group).pack() # entry inside this group
Canvas – The Drawing Boardcanvas = tk.Canvas(parent, width=400, height=300, bg="white")width / height – in pixels.bg – background colour.scrollregion – defines a virtual canvas area (used with scrollbars)..create_line(x1, y1, x2, y2, fill="red", width=2).create_rectangle(x1, y1, x2, y2, fill="blue", outline="black").create_oval(x1, y1, x2, y2, fill="green").create_text(x, y, text="Hello", font=("Arial", 12)).create_image(x, y, image=photo).move(item_id, dx, dy) – moves an item..delete(item_id) – removes an item..itemconfig(item_id, options) – changes an item's attributes.c = tk.Canvas(root, width=200, height=100, bg="lightyellow")
rect = c.create_rectangle(50, 25, 150, 75, fill="red")
c.pack()
Menu – The Top‑Level Menu Barmenubar = tk.Menu(root)root.config(menu=menubar)file_menu = tk.Menu(menubar, tearoff=0)menubar.add_cascade(label="File", menu=file_menu)file_menu.add_command(label="Open", command=open_func), file_menu.add_separator(), etc.tearoff=0 – disables the dotted line that lets you detach the menu.underline – keyboard shortcut (e.g., underline=0 for "F" in "File")..add_command(), .add_cascade(), .add_separator(), .add_checkbutton(), .add_radiobutton().menubar = tk.Menu(root)
root.config(menu=menubar)
file_menu = tk.Menu(menubar, tearoff=0)
menubar.add_cascade(label="File", menu=file_menu)
file_menu.add_command(label="Exit", command=root.destroy)
Scrollbar – The Navigation HelperText, Listbox, Canvas).Scrollbar does not work alone; it must be linked to a scrollable widget using a two‑way binding.scroll = tk.Scrollbar(parent, orient=tk.VERTICAL)yscrollcommand (or xscrollcommand) to the scrollbar's .set method.command to the widget's .yview (or .xview) method.listbox = tk.Listbox(root, height=4)
scroll = tk.Scrollbar(root, orient=tk.VERTICAL, command=listbox.yview)
listbox.config(yscrollcommand=scroll.set)
listbox.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
scroll.pack(side=tk.RIGHT, fill=tk.Y)
You pass options as keyword arguments:
btn = tk.Button(root, text="Click", font=("Arial", 10), bg="yellow")
.config() (or .configure())btn.config(text="New Label", bg="blue")
You can change almost any option at any time.
.cget()current_text = btn.cget("text")
print(current_text) # Prints "New Label"
.keys()print(btn.keys()) # Lists all configurable option names
textvariable vs. texttextvariable (e.g., my_var = tk.StringVar()) and bind it to a widget, the widget automatically updates when my_var.set() is called. This is more efficient than repeatedly calling .config().var = tk.StringVar()
label = tk.Label(root, textvariable=var)
var.set("Initial") # Label updates instantly!
Every widget inherits from the BaseWidget class and shares these methods:
.config(**options) – change one or more options..cget(option) – get the value of an option..destroy() – delete the widget..winfo_*() – a family of methods to get window information (e.g., .winfo_width(), .winfo_height(), .winfo_children())..focus_set() – give keyboard focus to this widget..bind(event, callback) – bind an event to a function (keyboard, mouse, etc.)..tk – returns the Tcl interpreter object (rarely needed).CheckbuttonRadiobuttonListboxScaleEntry widget?
.get().text().retrieve().content()password="*"show="*"mask="*"hidden=TrueLabelEntryTextCanvasFrame widget must always have a background colour set, otherwise it is invisible.Radiobutton widgets that share the same variable automatically belong to the same group.Listbox widget allows the user to type directly into the list.Canvas widget..config() on a widget can only be done once—after creation, the options are locked.Listbox, you use listbox.insert(tk.____, "New Item").Scale widget uses the parameter from_ because ____ is a reserved Python keyword.Entry widget is entry.delete(0, tk.____).Scrollbar to a Text widget, you set the yscrollcommand option of the Text widget to scrollbar.____.Canvas method to draw a rectangle is .create_____(x1, y1, x2, y2, ...).Match the widget to its primary method:
| Widget | Method |
|---|---|
A. Entry |
.curselection() |
B. Text |
.add_cascade() |
C. Listbox |
.create_line() |
D. Canvas |
.get(1.0, tk.END) |
E. Menu |
.insert(0, "text") |
Write a Tkinter application that contains the following widgets:
Label with the text "User Registration".Entry widgets (for username and password) with appropriate labels placed before them.Checkbutton labelled "Remember Me".Button labelled "Register" that, when clicked, prints the current content of both entries and the checkbox state to the terminal.Radiobutton group with three options: "Admin", "User", "Guest" with an IntVar to store the selection.Frame to group the username/password entries together and another Frame for the radiobuttons.Scale from 1 to 10 for "Experience Level".Create a window with a large Text widget and a vertical Scrollbar that is properly linked. Also add a Button at the bottom that, when clicked, prints all the text in the console.
Write a script that draws a yellow sun (a circle) in the top‑left corner and a green rectangle (representing grass) at the bottom of a Canvas that is 400x300 pixels. Add a Button that, when clicked, moves the sun 10 pixels to the right (use .move()).
Create a window with a Label that says "Click to change". Add a Button below it. Every time the button is clicked, change the Label's text to the current time (strftime) and change its background colour to a random colour (use random.choice from a list). Use .config() to achieve this.
Demonstrate your mastery of Tkinter widgets by building a functional registration form, analysing code, and researching deeper capabilities.
Write a Python script that creates a window with the following specifications:
Label at the top with "Create Your Account" in large bold font (size 16).Entry fields for: Full Name, Email, Phone Number.Radiobutton group for Male, Female, Other (use a StringVar).Checkbutton widgets: Sports, Music, Reading (use IntVar for each).Scale from 18 to 100 with a tick label every 10 years.Frame containers to organise the layout. You may use grid() inside frames and pack() for the outer structure.Examine the following code snippet. It is supposed to create a simple ordering system with a listbox, but it contains four logical or syntactical errors. Identify each error, explain why it is a problem, and provide the corrected code.
import tkinter as tk
root = tk.Tk()
root.title("Order")
items = ["Pizza", "Burger", "Pasta", "Salad"]
listbox = tk.Listbox(root, height=4, selectmode=tk.MULTIPLE)
for item in items:
listbox.insert(0, item) # Error 1
listbox.pack()
def show_order():
selected = listbox.get(tk.ACTIVE) # Error 2
print("You selected:", selected)
btn = tk.Button(root, text="Show Order", command=show_order)
btn.pack()
# Error 3: Scrollbar is created but never linked or packed properly
scroll = tk.Scrollbar(root, orient=tk.HORIZONTAL)
scroll.pack(side=tk.RIGHT, fill=tk.Y)
# Error 4: Missing the mainloop call
Corrected code:
import tkinter as tk
root = tk.Tk()
root.title("Order")
items = ["Pizza", "Burger", "Pasta", "Salad"]
listbox = tk.Listbox(root, height=4, selectmode=tk.MULTIPLE)
for item in items:
listbox.insert(tk.END, item)
listbox.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
scroll = tk.Scrollbar(root, orient=tk.VERTICAL, command=listbox.yview)
listbox.config(yscrollcommand=scroll.set)
scroll.pack(side=tk.RIGHT, fill=tk.Y)
def show_order():
selected_indices = listbox.curselection()
selected_items = [listbox.get(i) for i in selected_indices]
print("You selected:", selected_items)
btn = tk.Button(root, text="Show Order", command=show_order)
btn.pack()
root.mainloop()
PanedWindow (5 points)Research the PanedWindow widget (not covered in detail above). Write a short paragraph (4‑6 sentences) explaining:
Frame.PanedWindow with two Label widgets inside.Write a small script that creates an Entry widget and a Label. Bind the <KeyRelease> event to the Entry so that every time the user types a character, the label automatically updates to show the current text of the entry (character count or the text itself). Hint: Use .get() on the entry inside the callback.
Write a short paragraph (5‑7 sentences) answering: "Why is the Frame widget considered one of the most important widgets in Tkinter, even though it does not directly display any useful information to the user?" Use examples from this tutorial and your own reasoning.
| Term | Definition |
|---|---|
| Widget | A graphical UI element such as a button, label, or text field. |
| Parent Container | The widget that "owns" another widget. Destroying the parent destroys all children. |
| Geometry Manager | pack, grid, or place – decides the size and position of widgets. |
| Callback | A function passed to the command option that runs when a widget is activated. |
| Variable Class | StringVar, IntVar, DoubleVar, BooleanVar – special Tkinter variables that synchronise with widgets automatically. |
| Index | A way to refer to a position in a Text or Listbox (e.g., 1.0 for line 1, column 0). |
| Binding | Connecting an event (e.g., key press) to a function using .bind(). |
https://docs.python.org/3/library/tkinter.html#widgetsThis tutorial is designed to take approximately 3 hours of study, lab work, and homework. By the end, you should be comfortable creating any basic GUI using the most common Tkinter widgets and understand how to configure and manipulate them dynamically.