API Reference¶
All public symbols are importable directly from qtshadcn:
from qtshadcn import (
qsettings,
ThemeMode,
setThemeMode,
toggleThemeMode,
themeMode,
isDarkTheme,
setTheme,
getTheme,
setStyleSheet,
getStyleSheet,
SystemThemeWatcher,
ShadcnTheme,
ShadcnThemeTokens,
ThemeParseError,
)
Qt classes should be imported from the binding you are using:
Supported bindings: PySide6, PyQt6.
Functions¶
setThemeMode¶
def setThemeMode(
mode: ThemeMode | str,
*,
target: QtWidgets.QWidget | None = None,
save: bool = True,
) -> None
Set the active theme mode and re-render the stylesheet.
Parameters:
| Name | Type | Description |
|---|---|---|
mode |
ThemeMode \| str |
ThemeMode.AUTO, ThemeMode.LIGHT, ThemeMode.DARK, or "auto", "light", "dark". |
target |
QtWidgets.QWidget \| None |
When provided, applies the stylesheet only to that widget subtree instead of QApplication.instance(). Default None applies globally. |
save |
bool |
When True (default), persist the mode to config/theme_mode.json. |
toggleThemeMode¶
Cycle the theme mode: auto → light → dark → auto.
Parameters:
| Name | Type | Description |
|---|---|---|
target |
QtWidgets.QWidget \| None |
When provided, applies the stylesheet only to that widget subtree. Default None applies globally. |
save |
bool |
When True (default), persist the mode to config/theme_mode.json. |
themeMode¶
Return the active theme mode.
isDarkTheme¶
Return whether the resolved active palette is dark.
setTheme¶
def setTheme(
source: str | Path | None = None,
*,
custom_tokens: dict[str, Any] | None = None,
target: QtWidgets.QWidget | None = None,
save: bool = True,
) -> None
Load a QtShadcn XML or JSON theme, apply optional token overrides, and re-render the stylesheet.
Pipeline:
- Resolves the theme source path (defaults to bundled default XML theme when omitted)
- Parses the XML/JSON, applies
custom_tokens, resolves all color tokens - Persists the palette when
save=True - Renders QSS via Jinja2 and calls
target.setStyleSheet(qss)(orapp.setStyleSheet(qss)whentargetisNone)
Parameters:
| Name | Type | Description |
|---|---|---|
source |
str \| Path \| None |
Path to the .xml or .json theme file. Defaults to the bundled default XML theme. |
custom_tokens |
dict[str, Any] \| None |
Token overrides. Mode-specific when top-level keys are "light" and/or "dark". |
target |
QtWidgets.QWidget \| None |
When provided, applies the stylesheet only to that widget subtree. Default None applies globally. |
save |
bool |
When True (default), persist the palette to config/. |
Raises: ThemeParseError — if the file is missing, malformed, or has missing tokens.
getTheme¶
Return the active palette tokens for the current mode.
setStyleSheet¶
def setStyleSheet(
source: str | Path,
*,
target: QtWidgets.QWidget | None = None,
save: bool = True,
) -> None
Set the additional stylesheet layered on top of the base QSS.
source can be an inline QSS/Jinja string or a path to a .qss/.jinja file.
When save=True, the content is persisted to config/style.qss or
config/style.jinja.
Parameters:
| Name | Type | Description |
|---|---|---|
source |
str \| Path |
Inline QSS/Jinja string or path to a .qss/.jinja file. |
target |
QtWidgets.QWidget \| None |
When provided, applies the stylesheet only to that widget subtree. Default None applies globally. |
save |
bool |
When True (default), persist the content to config/. |
getStyleSheet¶
Return the current additional stylesheet content.
Window-scoped theming (v1 limitation)
Passing target scopes the current stylesheet rendering to that widget subtree.
Background signals such as font_family.valueChanged and SystemThemeWatcher
always re-render globally to QApplication and do not re-target specific widgets.
Styled Qt Widgets¶
QtShadcn renders shadcn-style QSS for common Qt widgets. Widget variants are selected with dynamic Qt properties.
QPushButton vs QToolButton¶
Use QPushButton for regular command buttons with text labels, form actions, dialog actions, and primary calls to action.
Use QToolButton for compact action primitives: icon buttons, toolbar-style controls, menu triggers, and toggle buttons. It shares the same visual variant names as QPushButton, but it is sized as an icon-oriented control and is not intended to replace text-first buttons.
Supported QToolButton dynamic properties:
| Property | Values | Description |
|---|---|---|
variant |
default, outline, secondary, ghost, destructive |
Visual intent. |
size |
icon-sm, icon, icon-lg |
Icon-oriented control size. |
Supported Widgets¶
QtShadcn ships QSS for these widgets:
QWidget— base background, foreground, and typography classesQLabel— typography and disabled stateQPushButton— variants, sizes, and disabled statesQToolButton— compact icon/action variantsQCheckBox— toggle controls with themed check icons and disabled statesQRadioButton— radio controls with themed checked iconsQLineEdit— input states including focus, disabled, and invalidQTextEditandQPlainTextEdit— textarea states including focus, disabled, and invalidQComboBoxandQFontComboBox— dropdowns, popups, and invalid statesQProgressBar— determinate, thin, and disabled statesQSlider— horizontal, vertical, tick, and disabled statesQScrollAreaandQScrollBar— scroll containers with pill-shaped, minimal tracksQToolBox— accordion with collapsible sections, dynamic chevrons, and outline/card variantsQDateEdit,QTimeEdit,QDateTimeEdit, andQCalendarWidget— date pickers with custom card popovers, dynamic chevron navigation, transparent headers, and seamlessly styled gridsQTableViewandQTableWidget— data tables with header styling, horizontal dividers, cell hover/selection, in-cell editors, and checkable indicatorsQGroupBoxandQFrame— layout containers
See the Roadmap for planned widget coverage.
Theme Mode¶
ThemeMode accepts the following values:
| Value | Behavior |
|---|---|
"auto" |
Detects OS light/dark preference via darkdetect (default) |
"light" |
Always uses the <light> palette |
"dark" |
Always uses the <dark> palette |
When the mode is "auto" and the OS preference cannot be detected, the internal
default of "dark" is used.
Models¶
ShadcnThemeTokens¶
Immutable Pydantic model holding the resolved tokens for a single palette (light or dark). Returned by getTheme.
All fields are str and required. Unknown XML tokens are ignored (extra="ignore").
The example values below come from the packaged default.xml light palette. They are not model fallbacks for missing custom theme tokens.
| Field | default.xml light value |
|---|---|
background |
#ffffff |
foreground |
#020617 |
card |
#ffffff |
card_foreground |
#020617 |
popover |
#ffffff |
popover_foreground |
#020617 |
primary |
#0f172a |
primary_foreground |
#f8fafc |
secondary |
#f1f5f9 |
secondary_foreground |
#0f172a |
accent |
#f1f5f9 |
accent_foreground |
#0f172a |
muted |
#f1f5f9 |
muted_foreground |
#64748b |
destructive |
#ef4444 |
destructive_foreground |
#f8fafc |
border |
#e2e8f0 |
input |
#e2e8f0 |
ring |
#0f172a |
radius |
8px |
font_family |
Open Sans |
spacing |
4px |
ShadcnTheme¶
Immutable Pydantic model holding both palettes.
| Field | Type |
|---|---|
light |
ShadcnThemeTokens |
dark |
ShadcnThemeTokens |
Exceptions¶
ThemeParseError¶
Raised by setTheme and parse_theme_source when the theme file cannot be loaded or is invalid.
Common causes:
- File not found
- File is not an XML document (JSON, CSS, and URLs are rejected explicitly)
- Missing a required token in
<light>or<dark> - Token value is empty