QtShadcn
Modern styling and theming framework for Qt/PySide and PyQt applications, inspired by shadcn/ui.
QtShadcn loads a local XML theme file containing <light> and <dark> palettes, resolves the design tokens, renders a QSS stylesheet via Jinja2, and applies it to your QApplication in one call.
Features
- Light & dark palettes — single XML file, both modes
- Auto mode — follows the OS theme via
darkdetect - Flexible scope — apply styles app-wide to
QApplicationor scope to a specificQWidget - Binding neutral — works with PySide6 or PyQt6 via a native internal shim
- Custom fonts — drop font files in the package
resources/fonts/directory - Disk cache — theme is re-rendered only when the source file changes
- App-provided Qt runtime — install the Qt binding your app already uses
- Themed icons — SVG check icons generated and cached at runtime
Requirements
- Python >= 3.11
- One of: PySide6 or PyQt6 (provided by your application environment)
Installation
# Install QtShadcn from PyPI
pip install qtshadcn
# Or with uv
uv add qtshadcn
QtShadcn does not bundle a Qt binding. Install the binding your application already uses:
# PySide6 (recommended)
pip install PySide6
# Or PyQt6
pip install PyQt6
Quick Start
import sys
from PySide6 import QtWidgets
from qtshadcn import setTheme, setThemeMode, getTheme
app = QtWidgets.QApplication(sys.argv)
setThemeMode("auto", save=False) # "auto" | "light" | "dark"
setTheme("path/to/my_theme.xml", save=False)
tokens = getTheme()
print(tokens.primary) # resolved hex color
label = QtWidgets.QLabel("Hello, QtShadcn!")
label.show()
sys.exit(app.exec())
Widget Gallery
Explore the supported widgets by running the gallery:
make gallery
The gallery includes a sidebar navigator, a light/dark toggle, and pages for every currently styled widget.
Supported Styled Widgets
QtShadcn currently ships QSS for:
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 variantsQGroupBoxandQFrame— layout containers
See the roadmap for what is planned next.
Theme File Format
A QtShadcn theme is a plain XML file with two palette sections:
<theme>
<light>
<background>#ffffff</background>
<foreground>#020617</foreground>
<primary>#0f172a</primary>
<primary_foreground>#f8fafc</primary_foreground>
<secondary>#f1f5f9</secondary>
<secondary_foreground>#0f172a</secondary_foreground>
<accent>#f1f5f9</accent>
<accent_foreground>#0f172a</accent_foreground>
<muted>#f1f5f9</muted>
<muted_foreground>#64748b</muted_foreground>
<destructive>#ef4444</destructive>
<destructive_foreground>#f8fafc</destructive_foreground>
<border>#e2e8f0</border>
<input>#e2e8f0</input>
<ring>#0f172a</ring>
<radius>8px</radius>
<font_family>Open Sans</font_family>
<spacing>4px</spacing>
<card>#ffffff</card>
<card_foreground>#020617</card_foreground>
<popover>#ffffff</popover>
<popover_foreground>#020617</popover_foreground>
</light>
<dark>
<!-- same tokens, dark values -->
</dark>
</theme>
Unknown tokens are silently ignored so you can extend the format freely.
API Reference
QtShadcn exposes a small, composable public API directly from the package root:
from qtshadcn import (
qsettings,
ThemeMode,
setThemeMode,
toggleThemeMode,
themeMode,
isDarkTheme,
setTheme,
getTheme,
setStyleSheet,
getStyleSheet,
SystemThemeWatcher,
)
setThemeMode(mode, *, target=None, save=True)
Set the active theme mode ("auto", "light", or "dark") and re-render the stylesheet. Pass target (QWidget) to scope the stylesheet to that window subtree instead of the entire QApplication.
toggleThemeMode(*, target=None, save=True)
Cycle the theme mode: auto → light → dark → auto. Pass target (QWidget) to scope to a specific window subtree.
themeMode() -> ThemeMode
Return the current ThemeMode.
isDarkTheme() -> bool
Return whether the resolved active palette is dark.
setTheme(source, *, custom_tokens=None, target=None, save=True)
Load a QtShadcn .xml or .json theme, apply optional token overrides, and re-render the stylesheet. Pass target (QWidget) to scope the stylesheet to that window subtree.
getTheme() -> ShadcnThemeTokens
Return the resolved tokens for the active mode.
setStyleSheet(source, *, target=None, save=True)
Set an additional stylesheet (inline QSS/Jinja string or .qss/.jinja file path) layered on top of the base QSS. Pass target (QWidget) to scope the stylesheet to that window subtree.
getStyleSheet() -> str
Return the current additional stylesheet content.
ShadcnThemeTokens
Immutable Pydantic model with one field per design token (background, primary, border, radius, font_family, ...). Every token is required in both XML palettes; missing tokens raise ThemeParseError.
Documentation
- Docs site: https://qtshadcn.readthedocs.io/
- Widget gallery:
examples/gallery/main.py(runmake gallery)
License
MIT
Metadata
Release files for qtshadcn 0.9.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| qtshadcn-0.9.0.tar.gz | 3.4 MB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| qtshadcn-0.9.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 6.2 MB
Release files / qtshadcn-0.9.0.tar.gz
| Download URL | qtshadcn-0.9.0.tar.gz |
|---|---|
| Size | 3.4 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
d34382aa322ec0a6f1231902af1506574c3db7cc7449b2669e859e8da784629a
|
|
BLAKE2b-256 checksum How to use checksums |
4d31e02a1c015b206be232c5a721d4748c4aa0a56fee83fdfe37d1d504603573
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 10, 2026.
Transparency logRelease files / qtshadcn-0.9.0-py3-none-any.whl
| Download URL | qtshadcn-0.9.0-py3-none-any.whl |
|---|---|
| Size | 2.8 MB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
e3b12bbc70d9d2d4fcf4d3a955d74f4e893e225a227bf187219d8f8c56af54e8
|
|
BLAKE2b-256 checksum How to use checksums |
297e1081c077304dace9f5053ad94518b33b1bfbb17d0ad27e3407bf88ac829a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 10, 2026.
Transparency log