How to Create Labels in Python with Tkinter

A bike shop client asked me for a tiny order-status window, and every line of text in it is a Tkinter Label: create it with tk.Label(root, text="..."), then place it with pack() or grid().

The trap is writing both on one line. pack() returns None, so your variable loses the label and every later update fails.

Quick answer: create the label, keep it in a variable, then call pack() on its own line:

status = tk.Label(root, text="Status: Processing", fg="white", bg="#d97706")
status.pack()

In this tutorial, I’ll rebuild that order panel on Python 3.12.5 with Tk 8.6: styling, changing text, wrapping, images and the errors I see most.

Create and style a Tkinter Label

My sample is order #1042 from Riverside Bikes: $84.99, still processing. Each line is its own Label:

import tkinter as tk

root = tk.Tk()
root.title("Riverside Bikes - Order status")
root.geometry("560x200")

title = tk.Label(root, text="Order #1042", font=("Segoe UI", 18, "bold"))
title.pack(pady=(20, 6))

status = tk.Label(root, text="Status: Processing", font=("Segoe UI", 12),
                  fg="white", bg="#d97706", padx=14, pady=6)
status.pack()

total = tk.Label(root, text="Order total: $84.99", font=("Segoe UI", 12),
                 relief="groove", bd=2, padx=10, pady=4)
total.pack(pady=12)
root.mainloop()
Tkinter window with a bold Order #1042 label, a white-on-orange Status Processing label and a grooved Order total $84.99 label
Three Labels: a bold title, a status badge with fg and bg colors, and a total with a groove border.

font takes a tuple of family, size and style. fg and bg accept color names or hex codes, while padx/pady add space inside the label.

relief="groove" with bd=2 draws the border. For hover colors and more color options, see how to change a Tkinter Label color.

How do I change Tkinter Label text after it’s created?

Same panel, plus a button that ships the order. The label reads a StringVar through textvariable:

import tkinter as tk

root = tk.Tk()
root.title("Order status")
root.geometry("420x170")

status_text = tk.StringVar(value="Status: Processing")
status = tk.Label(root, textvariable=status_text, font=("Segoe UI", 12),
                  fg="white", bg="#d97706", padx=14, pady=6)
status.pack(pady=(24, 12))

def mark_shipped():
    status_text.set("Status: Shipped on Nov 3, 2026")
    status.config(bg="#15803d")

ship = tk.Button(root, text="Mark as shipped", command=mark_shipped)
ship.pack()
root.mainloop()
Tkinter Label before and after the Mark as shipped button: Status Processing on orange changes to Shipped on Nov 3, 2026 on green
Left: the starting state. Right: after the button runs, the label shows the shipped date on a green background.

status.config(text=...) works too when you don’t need a variable. Both ways are compared in changing Tkinter Label text, and timers are in updating a Label dynamically.

To read the text back, call status.cget("text") or status_text.get(). More in getting Tkinter Label text.

Align and wrap long text in a Label

A Label shows text on one line until you set wraplength (in pixels). Same shop, now with a shipping note:

import tkinter as tk

root = tk.Tk()
root.title("Shipping note")
root.geometry("560x210")

note = ("Free shipping applies to orders over $75.00. Orders placed "
        "before 2 PM Eastern ship the same business day.")

tk.Label(root, text="Left-aligned, wrapped at 300 px:",
         anchor="w").pack(fill="x", padx=16, pady=(12, 0))
wrapped = tk.Label(root, text=note, wraplength=300, justify="left",
                   anchor="w", bg="#eef2ff", padx=8, pady=6)
wrapped.pack(fill="x", padx=16, pady=6)

centered = tk.Label(root, text="Questions? Call (555) 014-2026",
                    anchor="center", bg="#f1f5f9", pady=6)
centered.pack(fill="x", padx=16)
root.mainloop()
Tkinter window with a shipping note wrapped at 300 pixels and left-justified, plus a centered phone number label
The note breaks into lines at 300 px and stays left-justified; the phone line sits centered.

justify aligns the wrapped lines, while anchor places the whole text block inside the label ("w" = left). The Tkinter Label wrap text guide adds wrapping that follows window resizing.

Show an image in a Tkinter Label

For the shop logo, I pass a PhotoImage to image=. compound="left" keeps the text beside it:

import tkinter as tk

root = tk.Tk()
root.title("Riverside Bikes")
root.geometry("480x160")

logo = tk.PhotoImage(file="logo.png")     # keep this reference
brand = tk.Label(root, image=logo, text="  Riverside Bikes",
                 compound="left", font=("Segoe UI", 18, "bold"))
brand.pack(pady=28)
root.mainloop()
Tkinter Label showing a blue RB logo image to the left of the bold text Riverside Bikes
The 96 x 96 PNG logo and the text share one Label, with the image on the left.

PhotoImage reads PNG and GIF. For JPG files and resizing, use Pillow as shown in adding images in Tkinter.

Common Tkinter Label errors and how to fix them

The first one is the chained pack() from the intro. Here’s the real traceback:

import tkinter as tk

root = tk.Tk()
status = tk.Label(root, text="Processing").pack()
print(type(status))
status.config(text="Shipped")

Output:

<class 'NoneType'>
Traceback (most recent call last):
  File "C:\pyguides\runs\tklabel\ex_nonetype.py", line 6, in <module>
    status.config(text="Shipped")
    ^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'config'

type(status) printed NoneType, and config() raised an AttributeError. Split creation and pack() into two lines.

Important: if an image label shows up blank, the PhotoImage was garbage-collected. Keep it in a variable that outlives the function, like brand.image = logo.

You might also want these next:

Frequently asked questions

How do I create a label in Tkinter?

Call tk.Label(root, text="Hello"), store it in a variable, then call pack() or grid().

How do I change the font size of a Tkinter Label?

Pass a tuple such as font=("Segoe UI", 18), or call label.config(font=...) later.

How do I update a Label’s text?

Use label.config(text="...") or link a StringVar with textvariable and call set().

Why does my Label say ‘NoneType’ object has no attribute ‘config’?

You chained .pack() onto the constructor. Create the label first, then pack it.

Can a Tkinter Label have a transparent background?

Not directly. Set bg to the parent’s color instead, or draw the text on a Canvas.

Where are the Label options documented?

See tkinter in the Python docs.