Tkinter ttkbootstrap Canvas Widget Tutorial

The ttkbootstrap Canvas widget blends standard Tkinter vector drawing features with theme-aware background styling, allowing developers to create custom graphics, charts, and interactive shapes that adapt to active palette colors.

Tutorial Breakdown:

Part I: Basic Canvas Setup & Shape Drawing

ttkbootstrap Canvas Basic We drew shapes using coordinates and used Pack layout manager.
Canvas coordinates use pixels, supporting rectangles, ovals, lines, and custom text annotations.

import ttkbootstrap as ttk
from ttkbootstrap.constants import *

app = ttk.Window(title="Canvas Drawing Demo", themename="flatly")
app.geometry("420x300")

# Canvas widget with custom border and dimensions
canvas = ttk.Canvas(app, width=380, height=240, bg="#ecf0f1")
canvas.pack(padx=20, pady=25)

# Draw geometric shapes
canvas.create_rectangle(30, 30, 140, 110, fill="#3498db", outline="#2980b9", width=2)
canvas.create_oval(170, 30, 280, 110, fill="#e74c3c", outline="#c0392b", width=2)
canvas.create_line(30, 150, 350, 150, fill="#27ae60", width=3)
canvas.create_text(190, 190, text="ttkbootstrap Canvas Shapes", font=("Helvetica", 11, "bold"), fill="#2c3e50")

app.mainloop()
Practical Overview

The ttkbootstrap Canvas provides a high-performance drawing surface. While standard Tk widgets require manual color configuration during theme shifts, combining custom canvas tags with theme-aware variables allows seamless adaptation.

Part II: Live Dynamic Theme Switcher

ttkbootstrap Canvas Theme Switcher We used StringVar to track themes and used Grid layout manager.


Selecting theme radio buttons triggers live style updates across the application window 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="Canvas Theme Switcher", themename="superhero")
app.geometry("460x360")

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)

canvas_widget = ttk.Canvas(app, width=400, height=180, bg="#2b3e50")
canvas_widget.grid(row=2, column=0, columnspan=4, padx=15, pady=15)
canvas_widget.create_oval(150, 40, 250, 140, fill="#18bc9c", outline="#128f76", width=3)

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()

Part III: SQLite Database Integration (Saving Vector Drawing Attributes)

ttkbootstrap Canvas Database Integration We used SQLite database and SQLAlchemy to persist canvas drawing coordinates.
Upon launch, the application loads drawing parameters from SQLite to render shapes dynamically.

1️⃣ Creating SQLite Table & Inserting Shape Data

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\canvas_db.db"
engine = create_engine(DATABASE_URL, echo=False)

with engine.connect() as connection:
    connection.execute(text("CREATE TABLE IF NOT EXISTS shapes (id INTEGER PRIMARY KEY, shape_type TEXT NOT NULL, x1 INTEGER, y1 INTEGER, x2 INTEGER, y2 INTEGER, fill_color TEXT)"))
    
    result = connection.execute(text("SELECT COUNT(*) FROM shapes"))
    if result.scalar() == 0:
        connection.execute(text("INSERT INTO shapes (shape_type, x1, y1, x2, y2, fill_color) VALUES ('rectangle', 40, 40, 180, 140, '#2980b9'), ('oval', 210, 40, 350, 140, '#e67e22')"))
        connection.commit()

print("Canvas shapes database initial setup completed.")

2️⃣ Dynamic GUI Rendering Canvas Shapes from SQLite via SQLAlchemy

import ttkbootstrap as ttk
from ttkbootstrap.constants import *
from sqlalchemy import create_engine, text

DATABASE_URL = r"sqlite:///I:\My Drive\testing3\ttkbootstrap\canvas_db.db"
engine = create_engine(DATABASE_URL, echo=False)
connection = engine.connect()

def fetch_shapes():
    res = connection.execute(text("SELECT shape_type, x1, y1, x2, y2, fill_color FROM shapes"))
    return res.fetchall()

root = ttk.Window(title="Canvas SQLite Rendering", themename="flatly")
root.geometry("420x280")

canvas = ttk.Canvas(root, width=380, height=200, bg="#ffffff")
canvas.pack(padx=20, pady=20)

shapes_data = fetch_shapes()
for s in shapes_data:
    stype, x1, y1, x2, y2, fcolor = s
    if stype == "rectangle":
        canvas.create_rectangle(x1, y1, x2, y2, fill=fcolor, width=2)
    elif stype == "oval":
        canvas.create_oval(x1, y1, x2, y2, fill=fcolor, width=2)

lbl_status = ttk.Label(root, text=f"Loaded {len(shapes_data)} shapes from SQLite DB", bootstyle=SUCCESS, font=("Helvetica", 10))
lbl_status.pack(pady=5)

root.mainloop()
connection.close()

Part IV: Connecting to MySQL using SQLAlchemy

To connect your Canvas graphics database to a centralized MySQL database server, update the SQLAlchemy connection string:

# SQLite Connection (Commented Out)
# DATABASE_URL = r"sqlite:///I:\My Drive\testing3\ttkbootstrap\canvas_db.db"

# MySQL Connection string using PyMySQL
DATABASE_URL = "mysql+pymysql://username:password@localhost/student_db"

engine = create_engine(DATABASE_URL, echo=False)

Common Errors & Troubleshooting

Issue / Error Cause Recommended Solution
Canvas shapes disappear on theme switch Canvas background or drawing colors do not automatically update with ttkbootstrap themes. Bind a theme change event or re-render canvas elements inside your theme update callback function.
Coordinate mismatch or clipping Canvas width/height attributes are smaller than drawn shape bounds. Ensure canvas dimensions match or exceed the maximum coordinate offsets of your rendered shapes.

Frequently Asked Questions

Yes! Bind mouse events using canvas.bind("<B1-Motion>", on_drag_callback) to track coordinates and draw dynamically.

Call canvas.delete("all") to remove every item currently drawn on the canvas widget.



Subscribe to our YouTube Channel here



plus2net.com







Python Video Tutorials
Python SQLite Video Tutorials
Python MySQL Video Tutorials
Python Tkinter Video Tutorials
✖
We use cookies to improve your browsing experience. . Learn more
HTML MySQL PHP JavaScript ASP Photoshop Articles Contact us
© 2000-2026 plus2net.com All rights reserved worldwide Privacy Policy Disclaimer