theme — Theme
A theme plugin = a data preset (
theme.json, recolour and retoken) + optional UI QML slots (ui_extensions).
Declaration
{
"id": "example.cyberpunk.theme",
"name": "赛博朋克极客荧光主题",
"version": "1.0.0",
"target_app_version": "0.2",
"type": "theme",
"style_layer": "full",
"entrypoint": "theme.json",
"icon": "icon.svg",
"enabled": false,
"ui_extensions": {
"overlay_background": "CyberpunkBackground.qml",
"dialog_background": "CyberpunkDialogBackground.qml",
"settings_background": "CyberpunkSettingsBackground.qml",
"history_background": "CyberpunkHistoryBackground.qml",
"audio_level": "CyberpunkAudioLevel.qml"
},
"config_schema": [
{ "key": "cyber_glow", "label": "高能荧光光晕", "type": "boolean", "default": true }
]
}⚠️
window_backdropmust not be written intomod.json(it is ignored), put it intheme.jsoninstead.
A theme defaults to enabled: false (so installing it does not reskin everything right away).
theme.json
{
"theme_id": "example.cyberpunk.theme",
"name": "赛博朋克极客荧光主题",
"style_layer": "full",
"window_backdrop": "acrylic",
"tokens": {
"primary": "#00f0ff",
"primaryHover": "#38f9d7",
"primaryGlow": "rgba(0, 240, 255, 0.45)",
"solidBg": "#2563eb",
"solidBgHover": "#1d4ed8",
"glassBackground": "#070b19",
"glassCardBg": "rgba(9, 14, 32, 0.82)",
"glassCardBorder": "rgba(0, 240, 255, 0.38)",
"glassHoverBg": "rgba(0, 240, 255, 0.12)",
"glassHoverBorder": "rgba(0, 240, 255, 0.65)",
"neonBorderColor": "#00f0ff",
"neonGlowColor": "#ff007f",
"textPrimary": "#e0f7fa",
"textSecondary": "#80deea"
},
"style_overrides": {
"bgColor": "#070b19",
"textColor": "#00f0ff",
"sourceColor": "#ff2a85",
"neonBorderColor": "#00f0ff",
"neonGlowColor": "#ff007f",
"fontSize": 28,
"fontFamily": "MiSans VF",
"bgOpacity": 0.65,
"fontOpacity": 1.0
}
}1) Global design tokens tokens
tokens drive one-click reskinning of the whole app (cards, inputs, dropdowns, highlights, buttons). The host also accepts aliases:
| Token | Open aliases | Scope | Default fallback |
|---|---|---|---|
primary | — | Brand colour, focus accent, active slider, primary icons | #38bdf8 |
primaryHover | — | Accent hover highlight | #60a5fa |
primaryGlow | — | Accent outer glow / halo spot (an alpha value is recommended) | rgba(0.2, 0.5, 0.98, 0.28) |
solidBg | actionBg | Background of the solid action primary button | #2563eb |
solidBgHover | actionBgHover | Hover of the solid action primary button | #1d4ed8 |
activeBg | — | Selected-state background | Derived from primary |
activeBgHover | — | Selected-state hover background | Derived from primary |
glassBackground | surface | Dark frosted base background | #11141c |
glassCardBg | glassSurface | Global card backplate | rgba(1,1,1,0.05) |
glassCardBorder | glassBorder | Card outer edge border (neon themes inject their glowing outline here) | rgba(1,1,1,0.12) |
glassHoverBg | hoverBg | Hover background of cards / interactive items | rgba(1,1,1,0.12) |
glassHoverBorder | hoverBorder | Hover border of cards / interactive items | rgba(1,1,1,0.24) |
neonBorderColor | neonBorder | Main colour of the neon glowing border | Empty (inherit native) |
neonGlowColor | neonGlow | Secondary colour of the neon outer halo | Empty (inherit native) |
textPrimary | — | Level-1 headings and body text | #ffffff |
textSecondary | — | Secondary explanatory copy | #cbd5e1 |
textMuted | — | De-emphasised helper / unselected state | #94a3b8 |
textSubtle | — | Even weaker hint text | #64748b |
divider | — | Dividers and hairline inner strokes | rgba(1,1,1,0.08) |
success / successBg | — | Success semantic colour | #10b981 |
warning / warningBg | — | Warning semantic colour | #f59e0b |
danger / dangerBg | — | Danger semantic colour | #ef4444 |
fontFamily | — | Global font family | MiSans VF |
fontSizeSmall/Normal/Medium/Title/Large | — | Font size scale | 10 / 11 / 12 / 14 / 16 |
radiusSmall/Medium/Large/Pill | — | Corner radius scale | 6 / 8 / 12 / 14 |
Solid button readability: the
solidBgbackground must be dark enough for white text to reach a contrast ratio ≥ 4:1 (don't paint bright sky blue flat behind white text). The official defaults#2563eb/ hover#1d4ed8are already compliant values.
2) Caption overlay parameters style_overrides
| Key | Notes |
|---|---|
bgColor (alias background) | Caption window background |
textColor (alias text_color) | Translation colour |
sourceColor (alias source_color) | Source text colour |
neonBorderColor / neonGlowColor (snake_case aliases are equivalent) | Two-colour neon glow of the caption window |
fontSize / fontFamily | Font size (default 28) and font family (the font name is sanitised) |
bgOpacity / fontOpacity | 0.1–1.0 |
3) Layered stacking style_layer
| Value | Meaning |
|---|---|
full | Full preset. Mutually exclusive; disabling it restores the official default base automatically |
material | Overrides only the material / background dimension |
typography | Overrides only the text typesetting dimension |
effects | Overrides only the glow / decoration dimension |
Layers other than full can be mixed with each other, and can also stack on top of a full theme. A partial UI slot extension (say, only replacing the VU meter) usually uses effects.
4) Window material window_backdrop
Written at the top level of theme.json (writing it in mod.json makes it be ignored):
| Value | Effect |
|---|---|
acrylic | Windows Acrylic |
mica / mica_alt | Windows Mica / Mica Alt |
blur | Plain blur |
none | No system material (the theme paints its own backplate) |
5) When you need QML
For a theme's QML slots and background-drawing guidelines see:
- UI slots — the slot list, mutual exclusion rules, and the three background-slot guidelines: "must draw its own border / corner radius adapts / reacts to config changes"
- UI extensions (QML) — general QML patterns and
HostContext
Reference implementations: extensions/example_theme_cyberpunk/ (full + 5 slots), extensions/community_theme_glassmorphism/ (glass look), extensions/example_custom_waveform_ui/ (a partial extension replacing only audio_level).
Related
- UI slots
- UI extensions (QML)
- config_schema — theme switches such as
neon_glow - Example library
