The ttkbootstrap Combobox combines standard drop-down selection capabilities with Bootstrap styling (bootstyle). In this comprehensive tutorial, we cover basic Combobox styling, dynamic runtime theme switching, and full SQLite database synchronization using SQLAlchemy.
We used StringVar to store the dropdown selection and used Pack layout manager.
Combobox widget is enhanced with bootstyle=PRIMARY.
import ttkbootstrap as ttk
from ttkbootstrap.constants import *
def on_select(event):
label_msg.config(text=f"Selected: {combo_var.get()}")
app = ttk.Window(title="Combobox Bootstyle Demo", themename="flatly")
app.geometry("400x220")
combo_var = ttk.StringVar(value="Python")
languages = ["Python", "JavaScript", "PHP", "C++", "SQL"]
# Combobox with Primary bootstyle and read-only state
combo = ttk.Combobox(
app,
textvariable=combo_var,
values=languages,
state="readonly",
bootstyle=PRIMARY
)
combo.pack(padx=20, pady=20)
combo.bind("<<ComboboxSelected>>", on_select)
label_msg = ttk.Label(app, text="Selected: Python", font=("Helvetica", 11, "bold"), bootstyle=INFO)
label_msg.pack(padx=20, pady=10)
app.mainloop()
The ttkbootstrap Combobox extends standard Tkinter dropdowns by applying cohesive Bootstrap visual styles. Utilizing the bootstyle attribute (such as PRIMARY, SUCCESS, INFO, or DANGER), the border accent and focus highlight automatically adapt to match your active application theme. Listening to the <<ComboboxSelected>> virtual event enables real-time callbacks when users make a selection.
We used StringVar to track theme names and used Grid layout manager.
Selecting a theme in the Combobox dynamically modifies app.style.theme_use() at runtime.
import ttkbootstrap as ttk
from ttkbootstrap.constants import *
def change_theme(event):
selected_theme = theme_var.get()
app.style.theme_use(selected_theme)
label_info.config(text=f"Active Theme: {selected_theme}")
app = ttk.Window(title="Live Theme Switcher", themename="superhero")
app.geometry("520x240")
theme_var = ttk.StringVar(value="superhero")
available_themes = ["cosmo", "flatly", "journal", "darkly", "superhero", "solar", "cyborg"]
lbl_title = ttk.Label(app, text="Choose Application Theme:", font=("Helvetica", 11, "bold"))
lbl_title.grid(row=0, column=0, padx=15, pady=15, sticky="w")
theme_combo = ttk.Combobox(
app,
textvariable=theme_var,
values=available_themes,
state="readonly",
bootstyle=SUCCESS
)
theme_combo.grid(row=0, column=1, padx=15, pady=15)
theme_combo.bind("<<ComboboxSelected>>", change_theme)
label_info = ttk.Label(app, text="Active Theme: superhero", bootstyle=WARNING, font=("Helvetica", 10))
label_info.grid(row=1, column=0, columnspan=2, padx=15, pady=20)
app.mainloop()
We used SQLite database and SQLAlchemy to persist selections.
On launch, the Combobox pre-selects the stored value. On change, an immediate UPDATE is executed.
On start the application will load the last user saved option.
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\user_preference.db"
engine = create_engine(DATABASE_URL, echo=False)
with engine.connect() as connection:
connection.execute(text("CREATE TABLE IF NOT EXISTS settings (id INTEGER PRIMARY KEY, setting_name TEXT UNIQUE NOT NULL, setting_value TEXT NOT NULL)"))
result = connection.execute(text("SELECT COUNT(*) FROM settings WHERE setting_name='preferred_language'"))
if result.scalar() == 0:
connection.execute(text("INSERT INTO settings (setting_name, setting_value) VALUES ('preferred_language', 'Python')"))
connection.commit()
print("Database 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\user_preference.db"
engine = create_engine(DATABASE_URL, echo=False)
connection = engine.connect()
def get_stored_preference():
result = connection.execute(text("SELECT setting_value FROM settings WHERE setting_name='preferred_language'"))
row = result.fetchone()
return row[0] if row else "Python"
def update_db_preference(event):
selected_val = combo_var.get()
connection.execute(text("UPDATE settings SET setting_value = :val WHERE setting_name='preferred_language'"),
{"val": selected_val})
connection.commit()
label_status.config(text=f"Updated DB: {selected_val}")
root = ttk.Window(title="Combobox SQLite Integration", themename="flatly")
root.geometry("420x220")
initial_val = get_stored_preference()
combo_var = ttk.StringVar(value=initial_val)
options = ["Python", "JavaScript", "PHP", "C++", "SQL"]
lbl = ttk.Label(root, text="Default Programming Language:", font=("Helvetica", 11, "bold"))
lbl.grid(row=0, column=0, padx=15, pady=15, sticky="w")
combo = ttk.Combobox(
root,
textvariable=combo_var,
values=options,
state="readonly",
bootstyle=INFO
)
combo.grid(row=0, column=1, padx=15, pady=15)
combo.bind("<<ComboboxSelected>>", update_db_preference)
label_status = ttk.Label(root, text=f"Loaded from DB: {initial_val}", font=("Helvetica", 10), bootstyle=SUCCESS)
label_status.grid(row=1, column=0, columnspan=2, padx=15, pady=15)
root.mainloop()
connection.close()
To transition seamlessly to a centralized MySQL database server, update the SQLAlchemy connection string. The rest of the GUI layout code remains unchanged:
# SQLite Connection (Commented Out)
# DATABASE_URL = r"sqlite:///I:\My Drive\testing3\ttkbootstrap\user_preference.db"
# MySQL Connection string using PyMySQL
DATABASE_URL = "mysql+pymysql://username:password@localhost/student_db"
engine = create_engine(DATABASE_URL, echo=False)
connection = engine.connect()
| Issue / Error | Cause | Recommended Solution |
|---|---|---|
| SyntaxError: (unicode error) | Windows file paths contain backslashes like \u in path escape sequences. |
Use raw strings r"sqlite:///..." or forward slashes "sqlite:///..." in connection strings. |
| User types invalid option | Combobox state is left default ("normal"), allowing manual text entry. |
Set state="readonly" on the Combobox widget to restrict inputs strictly to values list. |
| Event callback not firing | Bound to wrong event or missing event parameter in handler function signature. |
Ensure binding uses "<<ComboboxSelected>>" and callback function defines def func(event):. |
combo.configure(bootstyle="danger") or combo.config(bootstyle=SUCCESS) to update the outline color state programmatically.
SELECT query returning a list of tuple values, extract the column array (e.g. [row[0] for row in results]), and pass it to combo['values'] = list_data.
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.