4. 使用ListView展示数据列表
任务目标
使用 Qt Quick 的 ListView 配合内置 ListModel 展示一组设备信息,实现列表滚动浏览、点击高亮选中项,并在右侧区域显示当前选中设备的详细信息。
环境依赖
Qt 5.15+(或 Qt 6.x),模块:QtQuick、QtQuick.Controls。使用 qmlscene 或 qml 运行器直接加载 QML 文件即可,无需 C++ 工程。
关键完整代码
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15
Rectangle {
width: 640
height: 480
color: "#f5f6fa"
// 设备数据模型
ListModel {
id: deviceModel
ListElement { name: "温度传感器"; type: "温湿度"; location: "A区-1号机房"; status: "在线"; value: "23.5°C" }
ListElement { name: "压力变送器"; type: "压力"; location: "B区-2号产线"; status: "告警"; value: "1.2MPa" }
ListElement { name: "流量计"; type: "流量"; location: "C区-3号管道"; status: "在线"; value: "3.8m³/h" }
ListElement { name: "振动分析仪"; type: "振动"; location: "D区-4号机组"; status: "离线"; value: "--" }
ListElement { name: "液位开关"; type: "液位"; location: "E区-5号储罐"; status: "在线"; value: "78%" }
ListElement { name: "电流互感器"; type: "电量"; location: "F区-6号配电柜"; status: "在线"; value: "12.5A" }
ListElement { name: "气动调节阀"; type: "执行器"; location: "G区-7号反应釜"; status: "告警"; value: "开度45%" }
}
RowLayout {
anchors.fill: parent
anchors.margins: 12
spacing: 12
// 左侧:设备列表
Rectangle {
Layout.preferredWidth: 280
Layout.fillHeight: true
color: "white"
radius: 6
border.color: "#dcdde1"
ListView {
id: deviceList
anchors.fill: parent
anchors.margins: 4
model: deviceModel
clip: true
focus: true
spacing: 2
// 当前选中项索引(初始选中第一项)
property int currentIndex: 0
delegate: Rectangle {
id: itemRect
width: ListView.view.width
height: 56
radius: 4
color: ListView.isCurrentItem ? "#3498db" : "transparent"
required property string name
required property string type
required property string status
Column {
anchors.left: parent.left
anchors.leftMargin: 12
anchors.verticalCenter: parent.verticalCenter
spacing: 4
Text {
text: name
font.pixelSize: 15
font.bold: true
color: ListView.isCurrentItem ? "white" : "#2c3e50"
}
Text {
text: type + " · " + status
font.pixelSize: 12
color: ListView.isCurrentItem ? "#ecf0f1" : "#7f8c8d"
}
}
MouseArea {
anchors.fill: parent
onClicked: {
deviceList.currentIndex = index
deviceList.forceActiveFocus()
}
}
}
// 键盘上下键切换选中
Keys.onUpPressed: if (currentIndex > 0) currentIndex--
Keys.onDownPressed: if (currentIndex < count - 1) currentIndex++
highlightFollowsCurrentItem: true
}
}
// 右侧:选中设备详情
Rectangle {
Layout.fillWidth: true
Layout.fillHeight: true
color: "white"
radius: 6
border.color: "#dcdde1"
Column {
anchors.centerIn: parent
spacing: 10
width: parent.width - 40
Text {
text: "设备详情"
font.pixelSize: 18
font.bold: true
color: "#2c3e50"
}
Rectangle {
width: parent.width
height: 1
color: "#ecf0f1"
}
Text {
text: "名称:" + deviceModel.get(deviceList.currentIndex).name
font.pixelSize: 14
color: "#34495e"
}
Text {
text: "类型:" + deviceModel.get(deviceList.currentIndex).type
font.pixelSize: 14
color: "#34495e"
}
Text {
text: "位置:" + deviceModel.get(deviceList.currentIndex).location
font.pixelSize: 14
color: "#34495e"
}
Text {
text: "状态:" + deviceModel.get(deviceList.currentIndex).status
font.pixelSize: 14
color: deviceModel.get(deviceList.currentIndex).status === "在线" ? "#27ae60" :
(deviceModel.get(deviceList.currentIndex).status === "告警" ? "#e67e22" : "#95a5a6")
}
Text {
text: "当前值:" + deviceModel.get(deviceList.currentIndex).value
font.pixelSize: 14
color: "#34495e"
}
}
}
}
}
运行方式
- 将上述代码保存为
DeviceList.qml。 - 在终端执行:
qmlscene DeviceList.qml(Qt 5)或qml DeviceList.qml(Qt 6)。
验证方法
- 列表展示:窗口左侧应显示 7 行设备条目,每行包含设备名称、类型与状态。
- 滚动:当窗口高度不足以显示全部条目时,可用鼠标滚轮在列表区域滚动浏览。
- 点击高亮:点击任意条目,该行背景变为蓝色,文字变为白色,表示选中。
- 键盘操作:点击列表后按键盘 ↑/↓ 键,选中项随之移动并保持高亮。
- 详情联动:右侧“设备详情”区域实时显示当前选中设备的名称、类型、位置、状态和当前值。初始状态默认选中第一项(温度传感器),右侧应显示对应信息。
关键实现说明
ListView的currentIndex属性控制当前选中项,highlightFollowsCurrentItem确保高亮跟随选中项移动。- 委托(delegate)中通过
ListView.isCurrentItem判断当前项是否为选中项,从而切换背景色与文字颜色。 - 右侧详情通过
deviceModel.get(deviceList.currentIndex)动态读取当前选中项数据,实现双向联动。 - 点击条目时手动设置
currentIndex并调用forceActiveFocus(),保证键盘事件能正确作用于列表。