六、QT Quick QML可视化组件(二):交互控件实战指南
本章详解QT Quick中ComboBox、SpinBox等常用交互组件,结合代码示例与最佳实践,助你构建友好现代UI。
六、QT Quick QML可视化组件(二):交互控件实战指南  -MakerLi

QT Quick与QML界面设计从入门到精通

第六章:可视化组件(二)—— ComboBox, SpinBox, Dial, Switch, TabBar, Menu, ToolTip


本章我们将继续探索QT Quick中常用的交互式可视化组件。这些组件是构建现代、友好用户界面的基石,提供了从简单选择到复杂导航的多种交互方式。我们将结合代码示例、属性说明和架构关系进行详细讲解。


组件概览与对比

  • ComboBox(组合框):下拉选择框,适合选项较多的场景,能有效节省空间。核心属性包括model(数据模型)、currentIndex(选中索引)、currentText(选中文本),常用信号有activated(选中触发)、currentIndexChanged(索引变更)。
  • SpinBox(数字调节框):支持输入或按钮微调整数值,适合精确数值场景。核心属性含value(当前值)、from/to(取值范围)、stepSize(步长),常用信号为valueModified(数值修改触发)。
  • Dial(刻度盘):圆形旋钮控件,通过旋转调节数值,模拟物理设备操作。核心属性与SpinBox一致,常用信号为moved(旋钮移动触发)。
  • Menu(菜单):弹出式命令列表,由按钮触发,用于组织操作。核心元素有MenuItem(菜单项)、MenuSeparator(分隔线),常用方法popup()(弹出)、open()(打开)。

详细属性与用法

1. ComboBox 详解

ComboBox是经典下拉选择控件,数据模型支持简单字符串列表或复杂ListModel,还可自定义下拉项样式:

import QtQuick.Controls 2.15

ComboBox {
    id: combo
    width: 200
    model: ["选项一", "选项二", "选项三", "选项四"]
    currentIndex: 1 // 默认选中第二项
    onActivated: {
        console.log("选中了:", currentText, "索引:", currentIndex)
    }
    // 自定义下拉项样式
    delegate: ItemDelegate {
        width: combo.width
        text: modelData
        highlighted: combo.highlightedIndex === index
        background: Rectangle {
            color: highlighted ? "#81C784" : "white"
        }
    }
}

它的核心属性说明:

  • model:支持数组或ListModel,默认null;
  • currentIndex:当前选中索引,默认-1(未选中);
  • currentText:选中项显示文本,默认空字符串;
  • editable:是否允许编辑输入,默认false;
  • displayText:主按钮显示的格式化文本,默认与currentText一致。

2. SpinBox 与 Dial 对比

两者均用于调节数值,但交互方式不同:SpinBox侧重精确输入,Dial侧重直观操作。可通过value属性双向绑定实现数值同步:

Row {
    spacing: 40
    SpinBox {
        id: spinbox
        from: 0
        to: 100
        value: 50
        stepSize: 5
        onValueModified: dial.value = value
    }
    Dial {
        id: dial
        from: 0
        to: 100
        value: 50
        stepSize: 5
        onMoved: spinbox.value = value
        background: Rectangle {
            color: "transparent"
            border.color: "#4CAF50"
            border.width: 3
            radius: width/2
        }
    }
}


3. Switch、TabBar 与 ToolTip 联动示例

这些组件常结合构建标签页导航和设置界面,实现状态联动与交互提示:

import QtQuick.Controls 2.15

Column {
    spacing: 20
    // 开关控件
    Switch {
        id: sw
        text: "启用高级功能"
        ToolTip.visible: hovered
        ToolTip.text: "开启后下方标签页将解锁更多选项"
    }
    // 标签栏
    TabBar {
        id: bar
        width: parent.width
        TabButton { text: "基本设置"; enabled: !sw.checked }
        TabButton { text: "高级设置"; enabled: sw.checked }
        TabButton { text: "关于" }
    }
    // 与TabBar对应的内容堆栈
    StackLayout {
        width: parent.width
        currentIndex: bar.currentIndex
        Rectangle { color: "#E8F5E9"; Label { text: "这里是基本设置..." } }
        Rectangle { color: "#FFF3E0"; Label { text: "高级功能已解锁!" } }
        Rectangle { color: "#E3F2FD"; Label { text: "软件信息..." } }
    }
}


组件关系架构

在QT Quick Controls 2体系中,组件层级与关联如下:

  • Control(基类):ComboBox、SpinBox、TabBar、Dial、Switch、Menu均继承自此基类,拥有通用属性与方法;
  • ToolTip:作为附加属性类,可附加到任意UI控件,提供hover或聚焦提示;
  • 常见关联:SpinBox与Dial通过value双向绑定同步数值,Menu由按钮触发,TabBar与StackLayout联动切换内容。

最佳实践与技巧

💡 设计提示:

  • 一致性:同类组件(如SpinBox和Dial)保持相同取值范围、步长,避免用户困惑;
  • 即时反馈:为重要交互(如Switch切换)提供视觉/文本反馈,比如ToolTip提示;
  • 可访问性:为ComboBox、Menu设置Accessible.nameAccessible.description,适配屏幕阅读器;
  • 性能优化:ComboBox数据量超1000项时,采用异步加载或自定义弹出滚动视图,避免卡顿;
  • 菜单分层:复杂功能用嵌套子菜单组织命令,保持主菜单简洁。

Menu 与 Action 的高级集成

将Menu与Action结合,可实现命令集中管理与复用,同一Action可同时用于工具栏、上下文菜单:

ApplicationWindow {
    id: window
    width: 400; height: 300
    // 定义Action
    Action {
        id: copyAction
        text: "复制"
        shortcut: "Ctrl+C"
        icon.name: "edit-copy"
        onTriggered: console.log("执行复制")
    }
    Action {
        id: pasteAction
        text: "粘贴"
        shortcut: "Ctrl+V"
        enabled: false // 可动态禁用
        onTriggered: console.log("执行粘贴")
    }
    // 工具栏按钮使用Action
    header: ToolBar {
        ToolButton { action: copyAction }
        ToolButton { action: pasteAction }
    }
    // 上下文菜单也使用相同的Action
    MouseArea {
        anchors.fill: parent
        acceptedButtons: Qt.RightButton
        onClicked: contextMenu.popup()
        Menu {
            id: contextMenu
            MenuItem { action: copyAction }
            MenuItem { action: pasteAction }
            MenuSeparator {}
            MenuItem { text: "自定义操作" }
        }
    }
}