Skip to main content

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
  • 🎯 Themed icons — SVG check icons generated and cached at runtime

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:

make gallery

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:

  1. Confirm the version in pyproject.toml matches the next semver release.
  2. Push a tag named vMAJOR.MINOR.PATCH for future releases.
  3. Let .github/workflows/publish-pypi.yml build and publish the wheel and sdist to PyPI.
  4. For an already-pushed tag such as v0.0.6, run the workflow manually from GitHub Actions after Trusted Publishing is configured.
  5. Use GitHub Releases for notes/tags, not .whl or .tar.gz assets.

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 classes
  • QPushButton — variants, sizes, and disabled states
  • QToolButton — compact icon/action variants
  • QLineEdit — input states including focus, disabled, and invalid
  • QTextEdit — textarea states including focus, disabled, and invalid
  • QCheckBox — toggle controls with themed check icons and disabled states

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 gallery       # run the widget gallery example
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.10

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for qtshadcn 0.0.10
File Size Uploaded
qtshadcn-0.0.10.tar.gz 2.6 MB Details

Built distribution (wheel)

Table of built distributions (wheels) for qtshadcn 0.0.10
File Interpreter ABI Platform
qtshadcn-0.0.10-py3-none-any.whl Python 3 none any Details

Total release size: 5.2 MB

Release files / qtshadcn-0.0.10.tar.gz

Download URL qtshadcn-0.0.10.tar.gz
Size 2.6 MB
Tags Source
SHA-256 checksum
How to use checksums
0d94ec147b085ba2dbb481795cb23fb2066c98ea06348ab099a0f52959f126e0
BLAKE2b-256 checksum
How to use checksums
df68a638ca95c141fa8e6d387ef557f06d969fb6f1791e12198243dae911641b
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 5, 2026.

Transparency log

Release files / qtshadcn-0.0.10-py3-none-any.whl

Download URL qtshadcn-0.0.10-py3-none-any.whl
Size 2.6 MB
Tags Python 3
SHA-256 checksum
How to use checksums
e4ca1b174ee57b1f67d4fb1301df48f5751c6b4b4276e6841c00078fcaeae0a7
BLAKE2b-256 checksum
How to use checksums
616c4cd5cf7ce9f7262c34b0d93dfb702ac566fca67cc2fe6183efcbeea33ea2
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 5, 2026.

Transparency log

Release history Release notifications | RSS feed

0.5.0

2 release files

0.4.0

2 release files

0.3.0

2 release files

0.2.0

2 release files

0.1.1

2 release files

0.1.0

2 release files

0.0.22

2 release files

This release

0.0.10 This release

2 release files

0.0.9

2 release files

0.0.7

2 release files

0.0.6

2 release files

0.0.5

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page