QtShadcn
快速开始

如何使用

主题接入与各组件用法示例。

1. 引入模块

QML 侧只需一行 import,组件与主题即可使用:

import QtShadcn

2. 主题接入(必做)

任何使用组件的页面/窗口先放一个 QtShadcnTheme(声明式入口,绑定 C++ ThemeManager 的 token 字典):

import QtQuick
import QtQuick.Controls as QQC
import QtShadcn

Window {
    id: root
    width: 640
    height: 480
    visible: true

    QtShadcnTheme { id: theme }

    color: theme.background   // 窗口底色跟主题走

    QQC.Button {
        anchors.centerIn: parent
        text: qsTr("点击")
        onClicked: theme.mode = theme.mode === "dark" ? "light" : "dark"
    }
}

Theme 属性一览(全部只读,组件直接绑定):

类别属性
颜色background foreground primary primaryForeground secondary secondaryForeground muted mutedForeground accent accentForeground destructive destructiveForeground border ring
形状radius(全局圆角)
间距spacingXs spacingSm spacingMd spacingLg spacingXl
原始字典tokens(动态索引,如 theme.tokens["primary"])

切换明暗:theme.mode = "dark" → 全局随动,所有绑定自动刷新。

3. ShadcnButton

ShadcnButton {
    text: qsTr("Deploy")
    variant: ShadcnButton.Variant.Primary  // Primary / Secondary / Outline / Ghost / Destructive / Link
    size: ShadcnButton.Size.Medium         // ExtraSmall / Small / Medium / Large / Icon
    loading: false
    onClicked: console.log("clicked")
}
  • variant × size 对照:Primary 实心主色、Secondary 次色、Outline 描边、Ghost 幽灵、Destructive 危险、Link 链接(hover 下划线)
  • 尺寸:XS=32 / Small=36 / Medium=40 / Large=44 / Icon=40(对齐 shadcn/ui)
  • loading:显示 Spinner 且禁用交互,文字半透明
  • disabled:继承 QQC enabled 属性,禁用态整体 50% 透明度
  • 键盘焦点:Tab 可达,聚焦显示 ring 焦点环(继承 QQC Button 行为)

4. ShadcnButtonGroup(按钮组)

ShadcnButtonGroup {
    ShadcnButton { text: qsTr("A"); variant: ShadcnButton.Variant.Primary }
    ShadcnButton { text: qsTr("B"); variant: ShadcnButton.Variant.Primary }
    ShadcnButton { text: qsTr("C"); variant: ShadcnButton.Variant.Primary }
}

组内按钮自动合并边框、只留两端圆角;无 border 的 variant(如 Primary)中间自动加 1px 分隔线。

5. ShadcnToggle / ShadcnToggleGroup(切换按钮)

// 独立切换(outline 样式 + checkable,选中时 accent 背景)
ShadcnToggle { text: qsTr("粗体") }
ShadcnToggle { text: qsTr("斜体"); checked: true }

// 多选组
ShadcnToggleGroup {
    ShadcnToggle { text: qsTr("左") }
    ShadcnToggle { text: qsTr("中"); checked: true }
    ShadcnToggle { text: qsTr("右") }
}

// 单选组(exclusive: true)
ShadcnToggleGroup {
    exclusive: true
    ShadcnToggle { text: qsTr("单选 1"); checked: true }
    ShadcnToggle { text: qsTr("单选 2") }
}

6. ShadcnSpinner(加载指示器)

ShadcnSpinner { width: 14; height: 14; color: theme.foreground }

ShadcnButton 的 loading: true 内部即用它。

6. ShadcnCard

ShadcnCard {
    width: 320

    ShadcnCardHeader {
        ShadcnCardTitle { text: qsTr("Card Title") }
        ShadcnCardDescription { text: qsTr("Card Description") }
    }
    ShadcnCardContent {
        Text { text: qsTr("内容区") }
    }
    ShadcnCardFooter {
        ShadcnButton { text: qsTr("取消"); variant: ShadcnButton.Variant.Outline; size: ShadcnButton.Size.Small }
        ShadcnButton { text: qsTr("确定"); size: ShadcnButton.Size.Small }
    }
}
  • 纯组合组件:Card = CardHeader / CardContent / CardFooter,对齐 shadcn 组合方式
  • size:ShadcnCard.Size.Default(内边距 24px)/ Small(16px)
  • 视觉:bg-card + 1px 前景色环(5% / dark 10%)+ shadow-md + theme.radius 圆角
  • Header:Title(16px Medium)+ Description(14px mutedForeground)垂直堆叠(gap 6px)
  • Footer:按钮区水平排列(gap 8px)

7. ShadcnInput

ShadcnInput {
    width: 320
    placeholderText: qsTr("请输入")
    echoMode: TextInput.Password   // 可选:密码模式
}
  • 基于 QQC.TextField(Basic style),h-9(36px) + 6px 圆角 + bg-input/50
  • 聚焦态:border 切 ring 色 + 3px 外环(ring 30% 透明)
  • disabled:opacity 50%
  • placeholder:mutedForeground 色

8. ShadcnBadge

Row {
    spacing: theme.spacingSm
    ShadcnBadge { text: qsTr("Default"); variant: ShadcnBadge.Variant.Default }
    ShadcnBadge { text: qsTr("Secondary"); variant: ShadcnBadge.Variant.Secondary }
    ShadcnBadge { text: qsTr("Destructive"); variant: ShadcnBadge.Variant.Destructive }
    ShadcnBadge { text: qsTr("Outline"); variant: ShadcnBadge.Variant.Outline }
    ShadcnBadge { text: qsTr("Ghost"); variant: ShadcnBadge.Variant.Ghost }
    ShadcnBadge { text: qsTr("Link"); variant: ShadcnBadge.Variant.Link }
}
  • 6 variant:default/secondary/destructive/outline/ghost/link
  • 高 20px 胶囊(radius 999),12px 字号 Medium
  • destructive 是 v4 新风格「透明底 + 红字」(旧版实心红底白字)

9. ShadcnSwitch

ShadcnSwitch { checked: true; size: ShadcnSwitch.Size.Default }  // Default | Small
  • 基于 QQC.Switch(Basic style),胶囊轨道
  • size Default:44×20 轨道 + 24×16 滑块(位移 16px)
  • size Small:28×16 轨道 + 16×12 滑块(位移 8px)
  • checked:bg-primary + 2px primary 边框 + 滑块居右
  • unchecked:bg-input/90 + 透明边框 + 滑块居左
  • focus:3px 外环(与 Input 一致)

10. ShadcnTabs

Column {
    spacing: theme.spacingMd

    ShadcnTabsList {
        id: tabs
        variant: "default"   // "default"(胶囊底容器)| "line"(下划线指示器)
        ShadcnTabsTrigger { text: qsTr("账户") }
        ShadcnTabsTrigger { text: qsTr("密码") }
    }
    StackLayout {
        currentIndex: tabs.currentIndex
        ShadcnTabsContent { Text { text: qsTr("账户内容") } }
        ShadcnTabsContent { Text { text: qsTr("密码内容") } }
    }
}
  • 基于 QQC.TabBar + TabButton(Basic style)
  • List variant:default = bg-muted 圆角容器;line = 透明底
  • Trigger:default 选中白底(bg-background);line 选中 2px 下划线(bottom -5px)
  • 联动:TabsList 暴露 currentIndex,外部用 StackLayout 绑定即可

11. ShadcnDialog

ShadcnButton { text: qsTr("打开"); onClicked: dialog.open() }
ShadcnDialog {
    id: dialog
    modal: true   // 默认

    ShadcnDialogContent {
        ShadcnDialogHeader {
            ShadcnDialogTitle { text: qsTr("确认操作?") }
            ShadcnDialogDescription { text: qsTr("此操作不可撤销。") }
        }
        // 业务内容
        ShadcnDialogFooter {
            ShadcnButton { text: qsTr("取消"); variant: ShadcnButton.Variant.Outline; onClicked: dialog.close() }
            ShadcnButton { text: qsTr("确认"); variant: ShadcnButton.Variant.Destructive; onClicked: dialog.close() }
        }
    }
}
  • 基于 QQC.Dialog(Basic style),max-w-md(448px) + 居中
  • 背景:bg-popover + 圆角 + 1px 环 + shadow-xl
  • 遮罩:QQC 默认 modal dim(黑 50%,比 shadcn 的 30% 略深)
  • 动画:fade + zoom-in-95,duration 100ms
  • 关闭:Esc + 点击遮罩
  • 组合:Dialog 内部直接放业务内容(Input/Card/Button 等)

完整示例(M3 组合)

import QtQuick
import QtQuick.Layouts
import QtShadcn

Rectangle {
    color: theme.background

    QtShadcnTheme { id: theme }

    ColumnLayout {
        spacing: theme.spacingMd
        anchors.centerIn: parent

        ShadcnCard { /* M3 落地后:卡片容器 */ }

        RowLayout {
            spacing: theme.spacingSm
            ShadcnButton { text: qsTr("新建"); onClicked: doCreate() }
            ShadcnButton {
                text: qsTr("提交")
                variant: ShadcnButton.Variant.Outline
                loading: busy
            }
        }
    }
}
Copyright © 2026