ListView 是 QML 中用于显示列表数据的高效组件,它只渲染当前可见的项目,非常适合显示大量数据。
基本用法
ListView {
id: listView
width: 200
height: 300
model: myModel
spacing: 5
clip: true
// 滚动条
ScrollBar.vertical: ScrollBar { }
// 分组设置
section {
property: "category"
delegate: sectionHeader
}
// 高亮设置
highlight: Rectangle {
color: "lightblue"
radius: 3
}
// 项目模板
delegate: ItemDelegate {
width: ListView.view.width
text: model.name
highlighted: ListView.isCurrentItem
}
// 键盘导航
Keys.onUpPressed: decrementCurrentIndex()
Keys.onDownPressed: incrementCurrentIndex()
}
ListView 属性表
核心属性
属性 | 类型 | 默认值 | 说明 |
---|---|---|---|
model |
variant | - | 数据模型 (数字/数组/ListModel/QAbstractItemModel) |
delegate |
Component | - | 定义每个项目的可视化组件 |
currentIndex |
int | -1 | 当前选中项的索引 |
count |
int | - | 只读,模型中的项目总数 |
spacing |
real | 0 | 项目之间的间距 |
布局属性
属性 | 类型 | 默认值 | 说明 |
---|---|---|---|
orientation |
enumeration | ListView.Vertical | 列表方向 (Vertical/Horizontal) |
layoutDirection |
enumeration | Qt.LeftToRight | 布局方向 (LeftToRight/RightToLeft) |
verticalLayoutDirection |
enumeration | ListView.TopToBottom | 垂直布局方向 (TopToBottom/BottomToTop) |
header |
Component | - | 列表头部组件 |
footer |
Component | - | 列表尾部组件 |
headerPositioning |
enumeration | ListView.InlineHeader | 头部定位方式 |
footerPositioning |
enumeration | ListView.InlineFooter | 尾部定位方式 |
滚动属性
属性 | 类型 | 默认值 | 说明 |
---|---|---|---|
contentWidth |
real | - | 只读,内容宽度 |
contentHeight |
real | - | 只读,内容高度 |
contentX |
real | 0 | 水平滚动位置 |
contentY |
real | 0 | 垂直滚动位置 |
flickableDirection |
enumeration | Flickable.AutoFlickDirection | 滚动方向 |
boundsBehavior |
enumeration | Flickable.StopAtBounds | 边界行为 |
flickDeceleration |
real | 1500 | 滚动减速速率 |
maximumFlickVelocity |
real | 2500 | 最大滚动速度 |
snapMode |
enumeration | ListView.NoSnap | 对齐模式 |
highlightRangeMode |
enumeration | ListView.NoHighlightRange | 高亮范围模式 |
分组属性 (section)
属性 | 类型 | 默认值 | 说明 |
---|---|---|---|
section.property |
string | - | 分组依据的属性名 |
section.criteria |
enumeration | ViewSection.FullString | 分组标准 |
section.delegate |
Component | - | 分组标题组件 |
section.labelPositioning |
enumeration | ViewSection.InlineLabels | 分组标签位置 |
性能优化属性
属性 | 类型 | 默认值 | 说明 |
---|---|---|---|
cacheBuffer |
int | 0 | 预渲染区域大小(像素) |
uniformItemSizes |
bool | false | 是否所有项目大小相同 |
reuseItems |
bool | false (Qt6默认为true) | 是否重用项目 |
视觉属性
属性 | 类型 | 默认值 | 说明 |
---|---|---|---|
highlight |
Component | - | 当前选中项的高亮组件 |
highlightFollowsCurrentItem |
bool | true | 高亮是否跟随当前项 |
highlightMoveDuration |
int | 150 | 高亮移动动画时长(ms) |
highlightResizeDuration |
int | 0 | 高亮大小调整动画时长(ms) |
keyNavigationWraps |
bool | false | 键盘导航是否循环 |
信号
信号 | 说明 |
---|---|
currentIndexChanged() |
当前索引变化时触发 |
currentItemChanged() |
当前项目变化时触发 |
contentXChanged() |
水平滚动位置变化时触发 |
contentYChanged() |
垂直滚动位置变化时触发 |
常用方法
方法 | 说明 |
---|---|
positionViewAtIndex(index, mode) |
滚动到指定索引 |
positionViewAtBeginning() |
滚动到开头 |
positionViewAtEnd() |
滚动到末尾 |
forceLayout() |
强制重新布局 |
incrementCurrentIndex() |
增加当前索引 |
decrementCurrentIndex() |
减少当前索引 |
数据模型
1. 简单数字模型
qml
model: 10 // 生成0-9的索引
2. JavaScript数组
qml
model: ["Apple", "Banana", "Orange"]
// delegate中通过 modelData 访问
Text { text: modelData }
3. ListModel (动态模型)
qml
ListModel {
id: myModel
ListElement { name: "Alice"; age: 25 }
ListElement { name: "Bob"; age: 30 }
}
ListView {
model: myModel
delegate: Text { text: name + ", " + age }
}
4. C++模型 (QAbstractItemModel)
qml
model: myCppModel // 需要在C++中注册
高级功能
分组显示 (section)
qml
ListView {
model: myModel
section {
property: "category" // 分组依据的属性
criteria: ViewSection.FullString
delegate: Rectangle {
width: parent.width
height: 30
color: "lightblue"
Text { text: section; anchors.centerIn: parent }
}
}
}
添加页眉页脚
qml
ListView {
header: Rectangle {
width: parent.width
height: 50
color: "yellow"
Text { text: "List Header"; anchors.centerIn: parent }
}
footer: Component {
Rectangle {
width: parent.width
height: 50
color: "orange"
Text { text: "End of List"; anchors.centerIn: parent }
}
}
}
动态更新模型
qml
Button {
text: "Add Item"
onClicked: myModel.append({"name": "New", "age": 0})
}
Button {
text: "Remove First"
onClicked: myModel.remove(0)
}
交互功能
选择项高亮
qml
ListView {
highlight: Rectangle {
color: "lightblue"
radius: 5
}
highlightFollowsCurrentItem: true
focus: true
}
点击处理
qml
delegate: MouseArea {
width: ListView.view.width
height: 50
onClicked: {
ListView.view.currentIndex = index
console.log("Clicked:", model.name)
}
// 内容...
}
性能优化
-
固定尺寸:为delegate设置明确的高度或使用
uniformItemSizes: true
-
异步加载:对复杂delegate使用Loader
-
缓存:增加
cacheBuffer
预渲染不可见项目 -
简化delegate:减少嵌套层次
qml
ListView {
cacheBuffer: 400 // 缓存额外200像素外的项目
uniformItemSizes: true // 所有项目大小相同
}
常见问题解决
1. 滚动条添加
qml
ListView {
ScrollBar.vertical: ScrollBar { }
}
2. 滚动到指定位置
qml
// 滚动到末尾
positionViewAtEnd()
// 滚动到特定索引
positionViewAtIndex(10, ListView.Beginning)
3. 键盘导航
qml
ListView {
focus: true
Keys.onUpPressed: currentIndex--
Keys.onDownPressed: currentIndex++
}
4. 下拉刷新实现
qml
ListView {
header: RefreshHeader {
refreshing: listModel.isRefreshing
onRefresh: listModel.refreshData()
}
}