The ttkbootstrap Labelframe widget extends standard Tkinter container frames by adding a labeled title border and theme-aware color palettes (`bootstyle`) to group related form controls cleanly.
We grouped widgets inside containers and used Pack layout manager.
Labelframe supports bootstyle=PRIMARY and bootstyle=SUCCESS to color-code border frames.
import ttkbootstrap as ttk
from ttkbootstrap.constants import *
app = ttk.Window(title="Labelframe Bootstyle Demo", themename="flatly")
app.geometry("420x260")
# Labelframe container with primary bootstyle border
lf = ttk.Labelframe(app, text="User Login Credentials", padding=20, bootstyle=PRIMARY)
lf.pack(padx=20, pady=20, fill=BOTH, expand=True)
lbl_user = ttk.Label(lf, text="Username: admin_user", font=("Helvetica", 10))
lbl_user.pack(anchor="w", pady=5)
lbl_role = ttk.Label(lf, text="Access Level: Superuser", font=("Helvetica", 10), bootstyle=SUCCESS)
lbl_role.pack(anchor="w", pady=5)
app.mainloop()
The ttkbootstrap Labelframe component groups related controls into distinct bordered sections with descriptive header titles. Applying bootstyle attributes (such as PRIMARY or SUCCESS) highlights the frame border using theme-consistent colors.
We used StringVar to track active themes and used Grid layout manager.
Selecting theme radio buttons triggers live style updates across container frames via app.style.theme_use().
import ttkbootstrap as ttk
from ttkbootstrap.constants import *
def change_theme():
selected_theme = theme_var.get()
app.style.theme_use(selected_theme)
label_info.config(text=f"Active Theme: {selected_theme}")
app = ttk.Window(title="Labelframe Theme Switcher", themename="superhero")
app.geometry("460x300")
theme_var = ttk.StringVar(value="superhero")
themes = ["cosmo", "flatly", "superhero", "darkly"]
lbl_title = ttk.Label(app, text="Select Application Theme:", font=("Helvetica", 11, "bold"))
lbl_title.grid(row=0, column=0, columnspan=4, padx=15, pady=10, sticky="w")
for idx, t_name in enumerate(themes):
rb = ttk.Radiobutton(
app,
text=t_name.capitalize(),
value=t_name,
variable=theme_var,
command=change_theme,
bootstyle="outline-toolbutton"
)
rb.grid(row=1, column=idx, padx=5, pady=5)
lf_widget = ttk.Labelframe(app, text="Container Panel", padding=15, bootstyle=WARNING)
lf_widget.grid(row=2, column=0, columnspan=4, padx=15, pady=15, sticky="ew")
lbl_inner = ttk.Label(lf_widget, text="Frame adjusts dynamically to active theme palette.", font=("Helvetica", 10))
lbl_inner.pack(anchor="w")
label_info = ttk.Label(app, text="Active Theme: superhero", bootstyle=SUCCESS, font=("Helvetica", 10))
label_info.grid(row=3, column=0, columnspan=4, padx=15, pady=5)
app.mainloop()
We used SQLite database and SQLAlchemy to persist panel properties.
Upon startup, the Labelframe loads its header title directly from database records.
from sqlalchemy import create_engine, text
# Use raw strings r"..." to prevent Unicode escape errors in Windows paths
DATABASE_URL = r"sqlite:///I:\My Drive\testing3\ttkbootstrap\containers_db.db"
engine = create_engine(DATABASE_URL, echo=False)
with engine.connect() as connection:
connection.execute(text("CREATE TABLE IF NOT EXISTS frames (id INTEGER PRIMARY KEY, frame_key TEXT UNIQUE NOT NULL, frame_title TEXT NOT NULL)"))
result = connection.execute(text("SELECT COUNT(*) FROM frames WHERE frame_key='main_panel'"))
if result.scalar() == 0:
connection.execute(text("INSERT INTO frames (frame_key, frame_title) VALUES ('main_panel', 'Authorized Personnel Portal')"))
connection.commit()
print("Containers database initial setup completed.")
import ttkbootstrap as ttk
from ttkbootstrap.constants import *
from sqlalchemy import create_engine, text
DATABASE_URL = r"sqlite:///I:\My Drive\testing3\ttkbootstrap\containers_db.db"
engine = create_engine(DATABASE_URL, echo=False)
connection = engine.connect()
def get_stored_title():
res = connection.execute(text("SELECT frame_title FROM frames WHERE frame_key='main_panel'"))
row = res.fetchone()
return row[0] if row else "Default Panel"
root = ttk.Window(title="Labelframe SQLite Sync", themename="flatly")
root.geometry("440x240")
panel_title = get_stored_title()
lf_db = ttk.Labelframe(root, text=panel_title, padding=20, bootstyle=SUCCESS)
lf_db.pack(padx=20, pady=20, fill=BOTH, expand=True)
lbl_info = ttk.Label(lf_db, text="Labelframe title loaded successfully from SQLite.", font=("Helvetica", 10), bootstyle=INFO)
lbl_info.pack(anchor="w")
root.mainloop()
connection.close()
To connect your Labelframe database application to a centralized MySQL database server, update the SQLAlchemy connection string:
# SQLite Connection (Commented Out)
# DATABASE_URL = r"sqlite:///I:\My Drive esting3 tkbootstrap\containers_db.db"
# MySQL Connection string using PyMySQL
DATABASE_URL = "mysql+pymysql://username:password@localhost/student_db"
engine = create_engine(DATABASE_URL, echo=False)
| Issue / Error | Cause | Recommended Solution |
|---|---|---|
| Child widgets overflow outside Labelframe | Using absolute positioning (`place`) or failing to apply expansion flags inside the frame. | Use pack(fill=BOTH, expand=True) or grid() configuration for children inside the frame container. |
| Bootstyle border color not rendering | Failing to pass the correct bootstyle constant or string identifier. | Ensure bootstyle keyword is correctly assigned, e.g., bootstyle=PRIMARY or bootstyle="success". |
labelanchor parameter (e.g., labelanchor="n", "ne", "e", "se", "s", "sw", "w", "nw") during initialization.
padding option (e.g., padding=15 or tuple padding like padding=(10, 5)).
Author & Instructor at plus2net
I write and maintain practical tutorials on Python, PHP, SQL, JavaScript, HTML, jQuery, and web development at plus2net. The tutorials focus on clear explanations, working examples, and code that readers can test and adapt while learning.