v2.2.0
ttkbootstrap 2.2.0 adds a command line, a way to carry a 1.x custom theme forward, and fixes the two things that made a custom theme awkward to use at all: __version__ never existed, and a theme could not be registered before the app it was meant to style.
The ttkb command line
Installing ttkbootstrap now installs a command, under two names — ttkb and ttkbootstrap — that run the same thing.
| Command | What it does |
|---|---|
ttkb version |
Print the installed version |
ttkb demo |
Open the widget demo |
ttkb convert-theme <file> |
Convert a 1.x theme file |
ttkb creator |
Open ttkcreator |
Each of those already existed as its own python -m invocation that nothing surfaced. Every python -m spelling still works, and is what to use when the scripts directory is not on PATH.
Carry a 1.x custom theme forward
A custom theme saved by ttkbootstrap 1.x now converts to the 2.x Theme(...).register() form with one command:
ttkb convert-theme user.py -o brand.pyIt reads any input a 1.x user could be holding — ttkcreator had three save paths, and each one's artifact converts: a user.py containing a USER_THEMES dict (what the Export button produced), a .py holding a ThemeDefinition(...) call (what Export theme definition wrote, and the one most likely to be sitting in your own project rather than inside the installed package), and a JSON file in the Style.load_user_themes format. Every theme in the file converts, under a single import.
The five accent anchors, the optional secondary, and the theme's background and foreground carry over. Three things deliberately do not:
- The plumbing colors —
border,inputbg,inputfg,selectbg,selectfg,active— becauseThemederives all six from the anchors and the surface. - The
lightanddarkaccents, because 2.x derives that pair from theneutralramp. A converted theme takes the default gray;Theme(neutral=...)tunes it. Noteneutralis the ramp base, not the palelightaccent — 1.x's near-whitelightcorresponds to ramp step[100], so passing it through asneutralwould wash outselectbgand an uncoloredsecondaryalong with it. - The opposite mode. A 1.x theme declares one mode, so the generated family declares that one and leaves the other commented out rather than inventing colors for it.
Converted output is close but not pixel-identical: an accent is re-derived per mode for contrast, so a dark theme's authored #6a5acd resolves to #887bd7.
The removal that made this necessary shipped back in 2.0 — the in-package themes/user.py store and ttkcreator's Import/Export buttons — but was never written down. Migrating to 2.0 now has a Saved themes move into your code section covering it.
Registering a theme before the app exists
Theme(...).register() raised RuntimeError: No Style instance yet unless an App was already running — but a theme is declared at the top of a file, which is exactly where no app exists. Worse, it made a custom theme unusable as an App(theme=...) argument: registration needed the app, and the app needed the name.
import ttkbootstrap as ttk
import brand # your converted theme module
app = ttk.App(theme="acme-light") # selectable straight awayThe theme is still validated at the register() call, so a missing anchor raises where it is written rather than later out of a window constructor. install_legacy_themes() gained the same treatment.
ttkbootstrap.__version__
import ttkbootstrap; ttkbootstrap.__version__ raised AttributeError — it had never existed, in any release. It now reports the installed distribution's version, read from the package metadata so pyproject.toml stays the one place the literal lives. It is declared in the type stub too, so ttk.__version__ resolves under pyright as well as at runtime.
The consequence of reading metadata is that it reports what was installed: an editable install keeps whatever metadata it was built with until it is reinstalled.
Documentation
- Reference › Command line is a new page.
- Theming & Colors and Migrating to 2.0 no longer say a theme must be registered after the
Appexists — they show the top-of-file form. Style.load_user_themeshad a one-line docstring that never stated the file format; it now specifies the JSON shape and the ways it differs from a converted theme.- The icons guide and the README point at tkinter-icons, the extension's current name.
- Reference › Scrollbar —
set()'s description had been shipping raw double backticks to the rendered page.
Testing
The suite is now density-independent (#1322). Four asset-geometry tests asserted exact unscaled pixel sizes, so a contributor on Windows at 125% — the factory default on most laptops — got four one-pixel failures on a clean checkout. The shared test root is pinned to standard density rather than the four assertions being patched, which also covers any other test carrying the same latent assumption.
Install: pip install --upgrade ttkbootstrap
Full change log: development/2_2_changes.md