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 - 🖥️ Binding neutral — works with PySide6, PyQt6, PySide2, or PyQt5
- 🖋 Custom fonts — drop font files in the package
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
Requirements
- Python ≥ 3.11
- One of: PySide6, PyQt6, PySide2, or PyQt5 (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, PySide2, PyQt5
pip install PyQt6
Widget Gallery
Explore the supported widgets by running the gallery:
uv run --extra dev python examples/gallery/main.py
The gallery includes a sidebar navigator, a light/dark toggle, and pages for every currently styled widget.
Distribution
Python distributions are published to PyPI. GitHub Releases are used for release notes and tags only; wheel and source distribution files should not be attached there once PyPI publishing is active.
Maintainer Release Checklist
Configure PyPI Trusted Publishing before the first release:
| PyPI field | Value |
|---|---|
| Project | qtshadcn |
| Owner | BugCodeX |
| Repository | QtShadcn |
| Workflow | publish-pypi.yml |
| Environment | pypi |
Release path:
- Confirm the version in
pyproject.tomlmatches the next semver release. - Push a tag named
vMAJOR.MINOR.PATCHfor future releases. - Let
.github/workflows/publish-pypi.ymlbuild and publish the wheel and sdist to PyPI. - For an already-pushed tag such as
v0.0.6, run the workflow manually from GitHub Actions after Trusted Publishing is configured. - Use GitHub Releases for notes/tags, not
.whlor.tar.gzassets.
Once the PyPI publish succeeds for the current release, any existing wheel and source distribution assets from earlier releases may be removed from GitHub Releases.
Local Twine upload should be treated as an explicit fallback only, not the default release path:
make build
uv run --extra dev twine upload dist/*
Quick Start
import sys
from qtshadcn._qt import QtWidgets
from qtshadcn import ThemeConfig, apply_theme
app = QtWidgets.QApplication(sys.argv)
config = ThemeConfig(
theme_source_path="path/to/my_theme.xml",
theme_mode="auto", # "auto" | "light" | "dark"
)
tokens = apply_theme(app, config)
print(tokens.primary) # resolved hex color
label = QtWidgets.QLabel("Hello, QtShadcn!")
label.show()
sys.exit(app.exec())
Supported Styled Widgets
QtShadcn currently ships QSS for:
QWidget— base background, foreground, and typography classesQPushButton— variants, sizes, and disabled statesQToolButton— compact icon/action variantsQLineEdit— input states including focus, disabled, and invalidQTextEdit— textarea states including focus, disabled, and invalid
See the gallery and 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>system-ui, sans-serif</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
apply_theme(app, config) → ShadcnThemeTokens
Parses the XML theme, renders the QSS stylesheet, and calls app.setStyleSheet().
| Parameter | Type | Description |
|---|---|---|
app |
QApplication |
The running Qt application instance |
config |
ThemeConfig | None |
Theme configuration; None reloads from cache |
Returns the active ShadcnThemeTokens (light or dark, resolved).
get_theme() → ShadcnTheme | None
Returns the full resolved theme (both palettes) from disk cache, or None if no theme has been applied yet.
ThemeConfig
| Field | Type | Default | Description |
|---|---|---|---|
theme_source_path |
str | None |
None |
Path to the .xml theme file |
theme_mode |
"auto" | "light" | "dark" |
"auto" |
Palette selection strategy |
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.
Development
This project uses uv and make.
make install-dev # set up the virtual environment
make lint # ruff check (report only)
make format # ruff format + ruff check --fix
make type-check # ty check
make test # pytest
make test-cov # pytest with HTML coverage report
make docs-serve # live-reload docs at http://127.0.0.1:8000
make build # wheel + sdist
make publish # show PyPI Trusted Publishing guidance
make clean # remove dist/, caches, .coverage
Run make help to see the full list.
License
MIT
Release files for qtshadcn 0.0.6
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.0.6.tar.gz | 4.6 MB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| qtshadcn-0.0.6-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 9.1 MB
Release files / qtshadcn-0.0.6.tar.gz
| Download URL | qtshadcn-0.0.6.tar.gz |
|---|---|
| Size | 4.6 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
7320a23645f8cd110d79e4608e6a38a5ccf1b2a29d9235218694e81eebfb150b
|
|
BLAKE2b-256 checksum How to use checksums |
764b83013c74c966357a7a0ef094b45422c4c4460aa4e06247b7fd9cf725be76
|
| 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 Aug 4, 2026.
Transparency logRelease files / qtshadcn-0.0.6-py3-none-any.whl
| Download URL | qtshadcn-0.0.6-py3-none-any.whl |
|---|---|
| Size | 4.5 MB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
e0c6e6e6d7236591ec8cb27a78f949965ebe1dee8fa7c5f0d5220dde18b81248
|
|
BLAKE2b-256 checksum How to use checksums |
a607d930151c3fa99593395a106148c7ce1106a6b89649e0515b6f1e6c7fbb00
|
| 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 Aug 4, 2026.
Transparency log