一、描述
ListView 继承自 Flickable,用作显示来自内置 QML 类型(如 ListModel 和 XmlListModel)或从 QAbstractItemModel 或 QAbstractListModel 继承的 C++ 中定义的自定义模型类创建的模型中的数据。
二、使用示例
import QtQuick 2.12
import QtQuick.Window 2.0
Window
{
id:root;
visible: true;
width: 200; height: 200
ListView
{
anchors.fill: parent
model:ListModel
{
ListElement{name: "张三";number: "555 3264"}
ListElement{name: "李四";number: "555 8426"}
ListElement{name: "王五";number: "555 0473"}
}
delegate: Text
{
text: name + ": " + number
}
}
}
import QtQuick 2.12
import QtQuick.Window 2.0
Window
{
id:root;
visible: true;
width: 200; height: 200
Component
{
id: contactDelegate
Item
{
width: 180;height: 40
Column
{
Text { text: '<b>Name:</b> ' + name }
Text { text: '<b>Number:</b> ' + number }
}
}
}
ListView
{
anchors.fill: parent
model:ListModel
{
ListElement{name: "张三";number: "555 3264"}
ListElement{name: "李四";number: "555 8426"}
ListElement{name: "王五";number: "555 0473"}
}
delegate:contactDelegate
highlight: Rectangle { color: "lightsteelblue"; radius: 5 }
focus: true
}
}
三、属性成员
1、highlightMoveDuration : int
highlightMoveVelocity : real
highlightResizeDuration : int
highlightResizeVelocity : real
这些属性控制高亮代理的移动速度和调整大小动画。
highlightFollowsCurrentItem 必须为 true 才能使这些属性生效。
速度属性的默认值为 400 像素/秒。
持续时间属性的默认值是 -1,即高亮将花费尽可能多的时间以设置的速度移动。
2、displayMarginBeginning : int
displayMarginEnd : int
此属性允许在视图几何图形之外显示委托。默认值为 0。
如果值不为零,则视图将在视图开始之前或结束之后创建额外的委托。该视图将创建尽可能多的委托,以适应指定的像素大小。
import QtQuick 2.12
import QtQuick.Window 2.0
Window
{
id:root;
visible: true;
width: 200; height: 200
ListView
{
width: 200; height: 15
// displayMarginBeginning:40;displayMarginEnd:40
model:ListModel
{
ListElement{name: "张三";number: "555 3264"}
ListElement{name: "李四";number: "555 8426"}
ListElement{name: "王五";number: "555 0473"}
}
delegate: Text
{
height:20;
width: 200
text: name + ": " + number
}
}
}
displayMarginBeginning:40;displayMarginEnd:40
3、highlightRangeMode : enumeration
preferredHighlightBegin : real
preferredHighlightEnd : real
这些属性定义了视图中突出显示的首选范围(对于当前项目)。
preferredHighlightBegin 值必须小于 preferredHighlightEnd 值。
highlightRangeMode 的有效值为:
- ListView.ApplyRange:视图尽可能将高亮保持在范围内。
- ListView.StrictlyEnforceRange:高亮不会超出范围。
- ListView.NoHighlightRange:默认值,无高亮范围。
import QtQuick 2.12
import QtQuick.Window 2.0
Window
{
width: 300
height: 150
visible: true
ListView
{
anchors.fill: parent
spacing: 5
model: 20
delegate:Rectangle
{
width: 30
color: ListView.view.currentIndex === index ? "red" : "steelblue"
height: ListView.view.height
Text
{
anchors.centerIn: parent
text: index
font.pixelSize: 20
}
}
orientation: Qt.Horizontal
preferredHighlightBegin: 135
preferredHighlightEnd: 165
highlightRangeMode: ListView.StrictlyEnforceRange
}
}
设置高亮的范围在135-165像素之间。
4、currentIndex : int
currentItem : Item
currentIndex 属性保存当前项的索引,而 currentItem 保存当前项。
将 currentIndex 设置为 -1 将清除突出显示并将 currentItem 设置为 null。
如果 highlightFollowsCurrentItem 为 true,则设置这些属性中的任何一个都会平滑滚动 ListView,以便当前项变为可见。
5、add : Transition
新项目添加到视图的转换。
import QtQuick 2.12
import QtQuick.Window 2.0
Window
{
id:root;
visible: true;
width: 200; height: 200
ListModel
{
id:model
ListElement{name: "张三";number: "555 3264"}
ListElement{name: "李四";number: "555 8426"}
ListElement{name: "王五";number: "555 0473"}
}
ListView
{
anchors.fill: parent
model:model
delegate: Text
{
text: name + ": " + number
}
add: Transition
{
NumberAnimation { properties: "x,y"; from: 100; duration: 1000 }
}
}
MouseArea
{
anchors.fill: parent
onPressed:
{
var data = {'name':"赵六",'number':"778 0899"};
model.append(data);
}
}
}
addDisplaced : Transition
当要把视图中现有的项目换成新项目(置换)时的转换。
可以和 add 配合使用:add 表被添加的那个的动画,此属性表示由于 add 操作受影响的其他项的动画。
MouseArea
{
anchors.fill: parent
onPressed:
{
var data = {'name':"赵六",'number':"778 0899"};
model.insert(1,data)
}
}
displaced : Transition
添加、移动、置换的通用转换。
如果视图指定了特定的 addDisplaced、moveDisplaced 、removeDisplaced 转换,则在相关操作发生时将使用更具体的转换而不是通用转换。
move : Transition
视图中项目移动操作的转换。
MouseArea
{
anchors.fill: parent
onPressed:
{
model.move(1,2,1)
}
}
moveDisplaced : Transition
可以和 move 一起使用,move 表示要移到的动画,此属性表示受 move 影响的其他项的动画。
import QtQuick 2.12
import QtQuick.Window 2.0
Window
{
id:root;
visible: true;
width: 200; height: 200
ListModel
{
id:model
ListElement{name: "张三";number: "555 3264"}
ListElement{name: "李四";number: "555 8426"}
ListElement{name: "王五";number: "555 0473"}
}
ListView
{
anchors.fill: parent
model:model
delegate: Text
{
text: name + ": " + number
}
move : Transition//李四
{
NumberAnimation { properties: "x,y"; from: 100; duration: 1000 }
}
moveDisplaced : Transition//王五
{
NumberAnimation { properties: "x,y"; from: 200; duration: 1000 }
}
}
MouseArea
{
anchors.fill: parent
onPressed:
{
model.move(1,2,1)//把李四移到王五的位置
}
}
}
populate : Transition
此属性包含要应用于最初为视图创建的项目的转换。
import QtQuick 2.12
import QtQuick.Window 2.0
Window
{
id:root;
visible: true;
width: 200; height: 200
ListModel
{
id:model
ListElement{name: "张三";number: "555 3264"}
ListElement{name: "李四";number: "555 8426"}
ListElement{name: "王五";number: "555 0473"}
}
ListView
{
id:list
anchors.fill: parent
model:model
delegate: Text
{
text: name + ": " + number
}
populate : Transition
{
NumberAnimation { properties: "x,y"; from: 100; duration: 1000 }
}
}
}
remove : Transition
项目移除时的转换。
import QtQuick 2.12
import QtQuick.Window 2.0
Window
{
id:root;
visible: true;
width: 200; height: 200
ListModel
{
id:model
ListElement{name: "张三";number: "555 3264"}
ListElement{name: "李四";number: "555 8426"}
ListElement{name: "王五";number: "555 0473"}
}
ListView
{
id:list
anchors.fill: parent
model:model
delegate: Text
{
text: name + ": " + number
}
remove : Transition
{
NumberAnimation { properties: "x,y"; to: 100; duration: 1000 }
}
}
MouseArea
{
anchors.fill: parent
onPressed:
{
model.remove(1,2)
}
}
}
removeDisplaced : Transition
受 move 影响的其他项目的转换。
import QtQuick 2.12
import QtQuick.Window 2.0
Window
{
id:root;
visible: true;
width: 200; height: 200
ListModel
{
id:model
ListElement{name: "张三";number: "555 3264"}
ListElement{name: "李四";number: "555 8426"}
ListElement{name: "王五";number: "555 0473"}
}
ListView
{
id:list
anchors.fill: parent
model:model
delegate: Text
{
text: name + ": " + number
}
remove : Transition
{
NumberAnimation { properties: "x,y"; to: 100; duration: 1000 }
}
removeDisplaced : Transition
{
NumberAnimation { properties: "rotation"; from:0; to: 360; duration: 2000 }
NumberAnimation { properties: "y"; duration: 2000 }
}
}
MouseArea
{
anchors.fill: parent
onPressed:
{
model.remove(1,1)
}
}
}
6、cacheBuffer : int
此属性确定委托是否保留在视图的可见区域之外。如果此值大于零,则视图可能会保留尽可能多的委托实例化。
此属性的默认值取决于平台,但通常是大于零的值。负值被忽略。
cacheBuffer 在 displayMarginBeginning 或 displayMarginEnd 指定的显示边距外运行。
7、count : int
此属性保存视图中的项目数。
8、currentSection : string
当前项的Section。见下面的属性21和附加属性4。
9、delegate : Component
委托提供了一个模板,定义了视图实例化的每个项目。
10、effectiveLayoutDirection : enumeration
此属性保存水平方向列表的有效布局方向。
当使用附加属性 LayoutMirroring::enabled 时,将镜像水平列表的视觉布局方向。但是,视图的layoutDirection 属性将保持不变。可以用此属性获取有效的布局方向。
11、footer : Component / header : Component
此属性包含要用作页脚 / 页眉的组件。页脚 / 页眉位于视图的末尾 / 头部。
footerItem : Item / headerItem : Item
页脚 / 页眉项目。页脚 / 页眉位于视图的末尾 / 头部。
footerPositioning : enumeration
此属性确定页脚项的位置。
- ListView.InlineFooter:默认,页脚位于 content 的末尾,并像普通项目一样与 content 一起移动。
- ListView.OverlayFooter:页脚位于视图的末尾。
- ListView.PullBackFooter:页脚位于视图的末尾。可以通过向后移动 content 来推开页脚,通过向前移动 content 来拉回。
如果未设置为ListView.InlineFooter,则无法从页脚按下并轻弹列表。
headerPositioning : enumeration
此属性确定页眉项的位置。
- ListView.InlineHeader:默认,页眉位于 content 的开头,并像普通项目一样与 content 一起移动。
- ListView.OverlayHeader:位于视图的开头。
- ListView.PullBackHeader:页眉位于视图的开头。可以通过向前移动 content 来推开页眉,通过向后移动 content 来拉回页眉。
如果未设置为 ListView.InlineHeader,则无法从页眉中按下并轻弹列表。
12、highlight : Component
此属性包含要用作突出显示的组件。
13、highlightFollowsCurrentItem : bool
此属性保存突出显示是否由视图管理。
如果此属性为 true(默认值),则突出显示将平滑移动以跟随当前项。否则,高亮不会被视图移动,任何移动都必须由高亮实现。
import QtQuick 2.12
import QtQuick.Window 2.0
Window
{
id:root;
visible: true;
width: 200; height: 200
Component
{
id: highlight
Rectangle
{
width: 180; height: 10
color: "lightsteelblue"; radius: 5
y: list.currentItem.y
Behavior on y
{
SpringAnimation
{
spring: 3
damping: 0.2
}
}
}
}
ListView
{
id: list
width: 180; height: 200
model:ListModel
{
ListElement{name: "张三";number: "555 3264"}
ListElement{name: "李四";number: "555 8426"}
ListElement{name: "王五";number: "555 0473"}
}
delegate: Text {font.pixelSize: 24; text: name }
highlight: highlight
highlightFollowsCurrentItem: false
focus: true
}
}
设为false,则高亮项组件与设置的组件保持一致。
highlightFollowsCurrentItem: true
为true则高亮由视图管理,会自适应项。
14、highlightItem : Item
保存了从高亮组件创建的高亮项目。
15、keyNavigationEnabled : bool
此属性保存是否启用列表的键盘导航。
16、keyNavigationWraps : bool
此属性保存列表是否包含键导航。
17、layoutDirection : enumeration
水平方向列表的布局方向。如果 orientation 为 Qt.Vertical,则设置此属性无效。
- Qt.LeftToRight:默认,项目将从左到右排列。
- Qt.RightToLeft:项目将从右到左排列。
verticalLayoutDirection : enumeration
垂直方向列表的布局方向。如果 orientation 为 Qt.Horizontal,则设置此属性无效。
- ListView.TopToBottom:默认,项目从视图顶部到视图底部排列。
- ListView.BottomToTop:项目从视图底部到视图顶部排列。
18、model : model
此属性保存为列表提供数据的模型。该模型提供用于在视图中创建项目的数据集。
19、orientation : enumeration
此属性保存列表的方向。
- ListView.Horizontal:项目水平排列
- ListView.Vertical:默认值,项目垂直布局
ListModel
{
id:model
ListElement{name: "张三";number: "555 3264"}
ListElement{name: "李四";number: "555 8426"}
ListElement{name: "王五";number: "555 0473"}
}
ListView
{
anchors.fill: parent
model:model
orientation : ListView.Horizontal
delegate: Text
{
text: name + ": " + number
}
}
20、reuseItems : bool
此属性使得能够重用从委托实例化的项目。默认为 false。
一般用法是配合 pooled() 附加信号使用的。
21、section 组
section.criteria : enumeration
section.delegate : Component
section.labelPositioning : enumeration
section.property : string
此组属性用作对Model内容的分组/分节展示。
section.property 包含作为每个分组基础的属性的名称。
section.criteria 保存了基于 section.property 形成分组的标准。
- ViewSection.FullString:默认,分组是根据 section.property 值创建的。
- ViewSection.FirstCharacter:根据 section.property 值的第一个字符创建部分。
section.delegate 保存每个分组的委托组件。
section.labelPositioning 确定当前与下一个分组是否贴在视图的开始/结束处,以及标签是否内嵌显示。
- ViewSection.InlineLabels:默认,部分标签在分隔部分的项目委托之间内联显示。
- ViewSection.CurrentLabelAtStart:当前部分标签在移动时粘在视图的开头。
- ViewSection.NextLabelAtEnd:下一部分标签在移动时粘在视图的末尾。
注意:启用 ViewSection.NextLabelAtEnd 需要视图提前扫描下一部分,这会影响性能,尤其是对于较慢的模型。
import QtQuick 2.12
import QtQuick.Window 2.0
Window
{
id:root;
visible: true;
width: 200; height: 400
Component
{
id: sectionHeading
Rectangle
{
width: 200
height: 40
color: "red"
required property string section
Text
{
text: parent.section + " -- 测试"
font.bold: true
font.pixelSize: 20
}
}
}
ListView
{
anchors.fill: parent
model:ListModel
{
ListElement{sex:"男";name: "张三"}
ListElement{sex:"男";name: "李四"}
ListElement{sex:"女";name: "王五"}
ListElement{sex:"女";name: "赵六"}
ListElement{sex:"女";name: "钱七"}
ListElement{sex:"男";name: "孙八"}
ListElement{sex:"女";name: "周九"}
}
delegate: Text
{
required property string name
text: name
font.pixelSize: 18
}
section.property: "sex"
section.criteria: ViewSection.FullString
section.delegate: sectionHeading
section.labelPositioning: ViewSection.InlineLabels
}
}
22、snapMode : enumeration
此属性决定了在拖动或轻弹后视图滚动的方式。
- ListView.NoSnap:默认,视图在可见区域内的任何位置停止。
- ListView.SnapToItem:视图以与视图开头对齐的项目固定。
- ListView.SnapOneItem:释放鼠标按钮时,视图与第一个可见项目之间的距离不超过一个项目。此模式对于一次移动一页特别有用。
23、spacing : real
此属性保存项目之间的间距。默认值为 0。
四、附加属性成员
1、ListView.delayRemove : bool
此附加属性保存委托是否可以被销毁。它附加到委托的每个实例。默认值为 false。
有时需要将项目的销毁延迟到动画完成。下面的示例委托确保动画在从列表中删除项目之前完成。
import QtQuick 2.12
import QtQuick.Window 2.0
Window
{
id:root;
visible: true;
width: 200; height: 200
ListModel
{
id:model
ListElement{name: "张三";number: "555 3264"}
ListElement{name: "李四";number: "555 8426"}
ListElement{name: "王五";number: "555 0473"}
}
Component
{
id: delegate
Text
{
id:delegateItem
text: name + ": " + number
SequentialAnimation
{
id: removeAnimation
PropertyAction { target: delegateItem; property: "ListView.delayRemove"; value: true }
NumberAnimation { target: delegateItem; property: "scale"; to: 0; duration: 1000; easing.type: Easing.InOutQuad }
// PropertyAction { target: delegateItem; property: "ListView.delayRemove"; value: false }
}
ListView.onRemove: removeAnimation.start()
}
}
ListView
{
anchors.fill: parent
model:model
delegate: delegate
MouseArea
{
anchors.fill: parent
onPressed:
{
model.remove(1,2)
}
}
}
这里不使用 Transition。
2、ListView.isCurrentItem : bool
此委托是否当前项。它附加到委托的每个实例。
此属性可用于调整当前项的外观,例如:
import QtQuick 2.12
import QtQuick.Window 2.0
Window
{
id:root;
visible: true;
width: 200; height: 200
ListModel
{
id:model
ListElement{name: "张三";number: "555 3264"}
ListElement{name: "李四";number: "555 8426"}
ListElement{name: "王五";number: "555 0473"}
}
ListView
{
id:list
anchors.fill: parent
model:model
focus: true
delegate: Text
{
text: name + ": " + number
color: ListView.isCurrentItem ? "blue" : "red"
}
}
}
3、ListView.view : ListView
此附加属性包含管理此委托实例的视图。
它附加到委托的每个实例,也附加到页眉、页脚、节和高亮委托。
4、ListView.nextSection : string
此附加属性保存下一个元素的部分。它附加到委托的每个实例。
ListView.previousSection : string
上一个元素,它附加到委托的每个实例。
ListView.section : string
此附加属性包含此元素的部分。它附加到委托的每个实例。
五、附加信号
1、add()
在将项目添加到视图后立即发出此信号。
2、pooled()
在将项目添加到重用池后发出此信号。仅当 reuseItems 属性为 true 时才会发出此信号。
可以使用它来暂停项目内正在进行的计时器或动画,或释放无法重复使用的资源。
3、remove()
在从视图中删除项目之前立即发出此附加信号。
如果指定了删除转换(remove : Transition),则在处理此信号后应用它,前提是 ListView.delayRemove 为 false。
4、reused()
该信号在项目被重用后发出。 至此,item已经从重用池中取出,放到 content view里面,index、row等模型属性也已经更新了。
仅当 reuseItems 属性为 true 时才会发出此信号。
六、成员函数
1、positionViewAtBeginning()
positionViewAtEnd()
将视图定位在开头或结尾。只能在组件完成后调用。
要在启动时定位视图,应由 Component.onCompleted 调用此方法。
例如,要在启动时将视图定位在末尾:
Component.onCompleted: positionViewAtEnd()
2、decrementCurrentIndex() / incrementCurrentIndex()
递减 / 递增当前索引。只能在组件完成后调用。
3、forceLayout()
强制布局,强制 ListView 立即响应模型中的任何未完成更改。只能在组件完成后调用。
4、int indexAt(real x, real y)
返回包含内容坐标中点 x, y 的可见项的索引。只能在组件完成后调用。
如果在指定点处没有项目,或者项目不可见,则返回 -1。
无论在滚动到视图时该点是否存在项目,如果项目在可见区域之外,则返回 -1。
5、Item itemAt(real x, real y)
返回包含内容坐标中点 x, y 的可见项。只能在组件完成后调用。
如果在指定的点没有项目,或者项目不可见,则返回 null。
如果项目在可见区域之外,则返回 null,无论项目在滚动到视图时是否存在于该点。
6、Item itemAtIndex(int index)
返回索引项。只能在组件完成后调用。
如果该索引没有项目,例如因为它还没有被创建,或者因为它已经被移出可见区域并从缓存中移除,则返回 null。
返回的值也不应该被存储,因为一旦控制离开调用范围,如果视图释放该项目,它就会变成 null。
7、positionViewAtIndex(int index, PositionMode mode)
定位视图,使 index 位于 mode 指定的位置。
- ListView.Beginning:将项目放置在视图的顶部(或左侧用于水平方向)。
- ListView.Center:将项目放置在视图的中心。
- ListView.End:将项目放置在视图的底部(或水平方向的右侧)。
- ListView.Visible:如果项目的任何部分可见,则不采取任何行动,否则将项目置于视野中。
- ListView.Contain:确保整个项目可见。如果项目大于视图,则项目位于视图的顶部(或左侧用于水平方向)。
- ListView.SnapPosition:将项目定位在 preferredHighlightBegin。此模式仅在 highlightRangeMode 为 StrictlyEnforceRange 或通过 snapMode 不为 NoSnap 时有效。
如果将视图定位在 index 处会导致在视图的开头或结尾显示空白空间,则视图将定位在边界处。
只能在组件完成后调用。要在启动时定位视图,应由 Component.onCompleted 调用此方法。例如,将视图放在最后:
Component.onCompleted: positionViewAtIndex(count - 1, ListView.Beginning)