QML输入控件:ComboBox(1)

目录

1. ComboBox基础介绍

1.1 基本属性

1.2 基本示例

2. 数据模型的使用

2.1 字符串列表模型

2.2 对象列表模型

2.3 ListModel动态模型

3. 自定义ComboBox外观

3.1 基本样式定制

3.2 使用Qt Quick Controls 2样式系统

4. 可编辑ComboBox

4.1 基本可编辑ComboBox

总结


ComboBox(组合框)是Qt Quick Controls模块中一个极其实用的控件,它结合了按钮和下拉列表的功能,为用户提供了一种从多个选项中选择一个值的便捷方式。本文将介绍ComboBox的基本属性、数据模型的使用、自定义外观以及编辑功能。


1. ComboBox基础介绍

ComboBox控件本质上是一个弹出式选择列表,当用户点击它时,会显示一个包含所有可选项目的下拉菜单。这种控件在表单填写、设置选项等场景中非常常见。

1.1 基本属性

ComboBox包含以下核心属性:

  • model:定义ComboBox中可选项的数据模型
  • currentIndex:当前选中项的索引
  • currentText:当前选中项的文本内容
  • editable:是否允许用户编辑内容
  • displayText:控件上显示的文本(可自定义格式)

1.2 基本示例

import QtQuick
import QtQuick.Controls

Window {
    width: 640
    height: 480
    visible: true
    title: qsTr("Hello World")

    ComboBox {
        id: basicComboBox
        anchors.centerIn: parent
        width: 200

        model: ["选项1", "选项2", "选项3", "选项4"]

        onActivated: {
            console.log("当前选择:", currentText)
        }
    }
}

这个简单示例创建了一个包含四个选项的ComboBox,并在用户选择不同选项时打印日志信息。

运行效果:


2. 数据模型的使用

ComboBox支持多种数据模型形式,为开发者提供了极大的灵活性。

2.1 字符串列表模型

最简单的方式是直接使用字符串数组:

model: ["苹果", "香蕉", "橙子", "葡萄"]

2.2 对象列表模型

对于更复杂的需求,可以使用对象列表:

model: [
    { text: "北京", value: "bj" },
    { text: "上海", value: "sh" },
    { text: "广州", value: "gz" }
]

// 使用时需要指定textRole
textRole: "text"

2.3 ListModel动态模型

对于需要动态修改的数据,ListModel是更好的选择:

import QtQuick
import QtQuick.Controls

Window {
    width: 640
    height: 480
    visible: true
    title: qsTr("Hello World")

    ListModel {
        id: cityModel
        ListElement { name: "北京"; code: "010" }
        ListElement { name: "上海"; code: "021" }
        ListElement { name: "广州"; code: "020" }
    }

    ComboBox {
        anchors.centerIn: parent
        model: cityModel
        textRole: "name"

        onActivated: {
            console.log("选中城市代码:", cityModel.get(currentIndex).code)
        }
    }
}

运行效果:

 


3. 自定义ComboBox外观

Qt Quick Controls允许开发者完全自定义ComboBox的外观,以适应不同的应用风格。

3.1 基本样式定制

import QtQuick
import QtQuick.Controls

Window {
    width: 640
    height: 480
    visible: true
    title: qsTr("Hello World")

    ComboBox {
        id: styledCombo
        width: 200
        anchors.centerIn: parent
        model: ["简约", "现代", "古典", "工业"]

        background: Rectangle {
            implicitWidth: 200
            implicitHeight: 40
            color: styledCombo.down ? "#d0d0d0" : "#f0f0f0"
            border.color: styledCombo.activeFocus ? "#999999" : "#f0f0f0"
            border.width: styledCombo.activeFocus ? 2 : 1
            radius: 4
        }

        contentItem: Text {
            text: styledCombo.displayText
            font: styledCombo.font
            color: styledCombo.activeFocus ? "blue" : "black"
            verticalAlignment: Text.AlignVCenter
            leftPadding: 10
        }

        indicator: Canvas {
            x: styledCombo.width - width - 10
            y: styledCombo.topPadding + (styledCombo.availableHeight - height) / 2
            width: 12
            height: 8

            onPaint: {
                var ctx = getContext("2d")
                ctx.reset()
                ctx.moveTo(0, 0)
                ctx.lineTo(width, 0)
                ctx.lineTo(width / 2, height)
                ctx.closePath()
                ctx.fillStyle = styledCombo.pressed ? "blue" : "gray"
                ctx.fill()
            }
        }

        popup: Popup {
            y: styledCombo.height
            width: styledCombo.width
            implicitHeight: contentItem.implicitHeight
            padding: 1

            contentItem: ListView {
                clip: true
                implicitHeight: contentHeight
                model: styledCombo.popup.visible ? styledCombo.delegateModel : null
                currentIndex: styledCombo.highlightedIndex

                ScrollIndicator.vertical: ScrollIndicator { }
            }

            background: Rectangle {
                border.color: "#f0f0f0"
                radius: 4
            }
        }
    }
}

 运行效果:


3.2 使用Qt Quick Controls 2样式系统

对于更专业的样式定制,可以使用Qt Quick Controls 2的样式系统:

import QtQuick
import QtQuick.Controls
import QtQuick.Controls.Material

Window {
    width: 640
    height: 480
    visible: true
    title: qsTr("Hello World")

    ComboBox {
        id: professionalCombo
        width: 250
        anchors.centerIn: parent
        model: ["专业选项1", "专业选项2", "专业选项3"]

        // 使用Material设计风格
        Material.background: Material.primary
        Material.foreground: Material.primaryTextColor
        Material.elevation: 2
    }
}

运行效果:

 


4. 可编辑ComboBox

ComboBox支持编辑功能,允许用户输入不在预定义选项中的值。

4.1 基本可编辑ComboBox

import QtQuick
import QtQuick.Controls

Window {
    width: 640
    height: 480
    visible: true
    title: qsTr("Hello World")

    ComboBox {
        anchors.centerIn: parent
        width: 200
        height: 40
        editable: true
        id: cbox
        model: ["100", "1000", "10000"]

        validator: RegularExpressionValidator {
            regularExpression: /^[A-Za-z0-9_]+$/
        }

        onAccepted: {
            if (find(editText) === -1) {
                model = model.concat(editText)
            }
        }
    }
}

用户可以在其中选择或输入值,输入的值会经过正则表达式验证(只能输入字母、数字和下划线),并且如果用户输入的新值不在下拉框的选项中,会将这个新值添加到下拉框的选项列表中。

运行效果:(输入新的数据,点击回车后,会追加到列表下方)

 


总结

本篇介绍了ComboBox的基本属性、数据模型的使用、自定义外观以及编辑功能,后面还会介绍一些高级用法。

完整代码:https://gitcode.com/u011186532/qml_demo/tree/main/qml_combobox

参考:ComboBox QML Type | Qt Quick Controls 6.8.2