目录
接上篇, 本文将继续介绍ComboBox示例, 包括:动态更新模型、带分组的ComboBox、以及带多列的ComboBox。
相关阅读:QML输入控件:ComboBox(1)-优快云博客
示例1: 动态更新模型
import QtQuick
import QtQuick.Controls
Window {
width: 640
height: 480
visible: true
title: qsTr("动态更新模型")
ComboBox {
id: dynamicCombo
width: 200
anchors.centerIn: parent
Component.onCompleted: {
// 模拟异步加载数据
Qt.callLater(function() {
dynamicCombo.model = ["动态加载1", "动态加载2", "动态加载3"]
})
}
Button {
anchors.left: parent.right
anchors.leftMargin: 10
text: "添加选项"
onClicked: {
if (dynamicCombo.model instanceof Array) {
var newModel = dynamicCombo.model.slice()
newModel.push("新选项" + (newModel.length + 1))
dynamicCombo.model = newModel
}
}
}
}
}
这段代码实现了一个简单的动态更新下拉菜单的界面:
- 窗口加载完成后,下拉菜单会通过模拟异步操作加载初始数据。
- 用户点击“添加选项”按钮时,会向下拉菜单中动态添加新的选项。
要点说明
- 使用 Qt.callLater 模拟异步加载数据,将初始数据设置到下拉菜单的模型中。
- 通过按钮点击事件,动态向 ComboBox 的模型中添加新选项,展示了如何操作和更新 QML 中的模型数据。
- 使用 slice() 方法复制数组,通过 push() 方法添加新元素,然后更新模型,展示了对数组模型的基本操作。
运行效果
示例2: 分组ComboBox
实现分组显示的下拉菜单:
import QtQuick
import QtQuick.Controls
Window {
width: 640
height: 480
visible: true
title: qsTr("分组ComboBox")
ComboBox {
id: comboBox
width: 250
height: 30
anchors.centerIn: parent
// 优化后的模型结构 - 统一使用display属性,用isGroup标记分组项
model: [
{ display: "水果", isGroup: true },
{ display: "苹果", isGroup: false },
{ display: "香蕉", isGroup: false },
{ display: "蔬菜", isGroup: true },
{ display: "胡萝卜", isGroup: false },
{ display: "西红柿", isGroup: false }
]
// 当前显示文本
displayText: currentIndex >= 0 ? model[currentIndex].display : "请选择"
// 初始不选择任何项
currentIndex: -1
// 优化后的委托实现
delegate: ItemDelegate {
width: parent.width
height: modelData.isGroup ? 30 : implicitHeight // 分组标题高度较小
enabled: !modelData.isGroup // 分组项不可选择
highlighted: comboBox.highlightedIndex === index && !modelData.isGroup
contentItem: Text {
text: modelData.display
font.bold: modelData.isGroup
color: modelData.isGroup ? "#999999" : (highlighted ? "#666666" : "#333333")
leftPadding: modelData.isGroup ? 10 : 20 // 分组项缩进较少
}
// 分组项的背景色
background: Rectangle {
color: modelData.isGroup ? "#f0f0f0" : "#ffffff"
radius: 2
}
// 处理点击事件,跳过分组项
onClicked: {
if (!modelData.isGroup) {
comboBox.currentIndex = index
comboBox.popup.close()
}
}
}
// 下拉框弹出时的样式调整
popup: Popup {
y: comboBox.height
width: comboBox.width
implicitHeight: contentItem.implicitHeight
padding: 1
contentItem: ListView {
clip: true
implicitHeight: contentHeight
model: comboBox.popup.visible ? comboBox.delegateModel : null
currentIndex: comboBox.highlightedIndex
// 添加分组分隔线
section {
property: "isGroup"
criteria: ViewSection.FullString
delegate: Rectangle {
width: parent.width
height: 1
color: "#eeeeee"
visible: section !== "true" // 只在分组之间显示分隔线
}
}
}
}
}
}
这段代码实现了一个带有分组功能的下拉菜单(ComboBox),通过自定义委托和分组逻辑,展示了如何在 QML 中创建具有分组标题和分隔线的动态下拉列表。
要点说明
- 使用带有 isGroup 属性的模型来区分分组标题和普通选项,通过 isGroup 标记分组项,实现了分组功能。
- 自定义了 delegate,为分组项和普通项设置了不同的样式(如字体加粗、背景色、高度等),并通过 enabled 属性使分组项不可选。
- 通过 displayText 属性动态显示当前选中的项,若未选择任何项则显示“请选择”。
- 在下拉列表中通过 section 属性添加了分组分隔线,仅在分组之间显示,增强了视觉效果。
- 在委托中处理点击事件,跳过分组项,确保只有普通项可被选中,并在选择后关闭下拉框。
- 自定义了 popup,调整了下拉框的样式和布局,使其与分组逻辑相匹配,确保分组项和普通项的显示效果一致。
运行效果
示例3: 多列ComboBox
实现多列显示的下拉菜单:
import QtQuick
import QtQuick.Controls
Window {
width: 640
height: 480
visible: true
title: qsTr("多列ComboBox")
ComboBox {
id: multiColumnCombo
width: 300
height: 30
anchors.centerIn: parent
delegate: ItemDelegate {
width: parent.width
Row {
spacing: 10
Text {
text: modelData.name
width: 100
elide: Text.ElideRight
}
Text {
text: modelData.code
width: 50
color: "gray"
}
Text {
text: modelData.region
width: 100
color: "gray"
}
}
}
model: [
{ name: "北京", code: "010", region: "华北" },
{ name: "上海", code: "021", region: "华东" },
{ name: "广州", code: "020", region: "华南" }
]
displayText: currentText + " (" + model[currentIndex].code + ")"
}
}
这段代码实现了一个多列的下拉菜单(ComboBox),展示了如何在 QML 中通过自定义委托(delegate)显示多列数据。
要点说明
- 模型:使用一个包含多个对象的数组作为模型,每个对象包含 name、code 和 region 三个字段,分别表示城市名称、区号和所属区域。
- 委托:自定义了 delegate,使用 Row 布局将每行数据分为三列显示。
- 动态显示文本:displayText 属性动态显示当前选中的城市名称和区号,格式为“城市名称 (区号)”。
运行效果
总结
本文主要展示了3个示例,分别为:
- 动态更新模型:如何通过异步加载和按钮交互动态更新 ComboBox 的数据模型;
- 分组ComboBox:实现了分组功能的 ComboBox,通过自定义委托和分组逻辑,展示了分组标题、分隔线和动态样式调整;
- 多列ComboBox:展示了如何通过自定义委托在 ComboBox 中显示多列数据。
完整工程:https://gitcode.com/u011186532/qml_demo/tree/main/qml_combobox