Getting Started¶
Requirements¶
- Python ≥ 3.11
- One of the supported Qt bindings: PySide6 or PyQt6
Installation¶
QtShadcn is published on PyPI. A Qt binding is intentionally not bundled; install the one your application already uses so your app controls the Qt runtime version.
Minimal Setup¶
1. Create a theme file¶
Save this as my_theme.xml next to your script:
<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>
<background>#020617</background>
<foreground>#f8fafc</foreground>
<primary>#f8fafc</primary>
<primary_foreground>#0f172a</primary_foreground>
<secondary>#1e293b</secondary>
<secondary_foreground>#f8fafc</secondary_foreground>
<accent>#1e293b</accent>
<accent_foreground>#f8fafc</accent_foreground>
<muted>#1e293b</muted>
<muted_foreground>#94a3b8</muted_foreground>
<destructive>#7f1d1d</destructive>
<destructive_foreground>#f8fafc</destructive_foreground>
<border>#1e293b</border>
<input>#1e293b</input>
<ring>#cbd5e1</ring>
<radius>8px</radius>
<font_family>Open Sans</font_family>
<spacing>4px</spacing>
<card>#020617</card>
<card_foreground>#f8fafc</card_foreground>
<popover>#020617</popover>
<popover_foreground>#f8fafc</popover_foreground>
</dark>
</theme>
2. Apply the theme¶
import sys
from PySide6 import QtWidgets
from qtshadcn import ThemeParseError, setTheme, setThemeMode, getTheme
app = QtWidgets.QApplication(sys.argv)
try:
setThemeMode("auto", save=False) # follows the OS — or use "light" / "dark"
setTheme("my_theme.xml", save=False)
except ThemeParseError as e:
print(f"Could not load theme: {e}")
sys.exit(1)
tokens = getTheme()
print(f"Active primary color: {tokens.primary}")
btn = QtWidgets.QPushButton("Hello, QtShadcn!")
btn.show()
sys.exit(app.exec())
Using the Default Theme¶
QtShadcn ships with a default theme. Load it by calling setTheme with no argument, or simply query the active tokens after setting the mode:
Using Bundled Fonts¶
QtShadcn includes Open Sans and Roboto under qtshadcn/resources/fonts/. To activate them, set font_family in your XML:
The fonts are registered automatically when the stylesheet is rendered.
Theme Mode Options¶
| Value | Behavior |
|---|---|
"auto" |
Follows the OS light/dark preference (default) |
"light" |
Always use the <light> palette |
"dark" |
Always use the <dark> palette |
setThemeMode accepts the string values "auto", "light", and "dark":
from qtshadcn import setTheme, setThemeMode
setThemeMode("dark", save=False)
setTheme("my_theme.xml", save=False)
Window-Scoped Theming¶
By default, QtShadcn applies the generated stylesheet to the entire application (QApplication.instance()). For applications with a single main window or when you want to style a specific window subtree independently, pass target to setThemeMode, setTheme, or setStyleSheet:
from PySide6 import QtWidgets
from qtshadcn import setTheme, setThemeMode
app = QtWidgets.QApplication([])
window = QtWidgets.QMainWindow()
# Scope the stylesheet to this window and its child dialogs
setThemeMode("dark", target=window, save=False)
setTheme("my_theme.xml", target=window, save=False)
window.show()
app.exec()
Window scoping speeds up theme switching in single-window applications by avoiding repolishing every widget across the entire process. Child dialogs (such as QColorDialog or QFileDialog parented to the window) inherit the window stylesheet, while independent sibling windows remain unstyled.
Supported Qt Bindings¶
QtShadcn supports two Qt bindings through a native shim:
- PySide6
- PyQt6
Choosing a binding¶
If only one supported binding is installed, the shim uses it automatically. If both are installed, PySide6 is preferred.
Import Qt classes from the binding you installed in your application code:
The public API remains the same regardless of which binding is active.