简介
Repeater 是一个非常特别又非常好用的类,它用来创建多个基于 Item 的组件,扔给它的 parent(通常是定位器或布局管理器)来管理。这是 Repeater 和 ListView 等类的一个显著不同。
Repeater 有三个属性,count 指示它创建了多少个基于 Item 的对象,model 指定数据模型, delegate 是待实例化的组件。delegate 是默认属性,在定义 Repeater 对象时通常不显式初始化。 itemAt(index)方法根据索引返回对应的 delegate 实例。
Repeater 对象会在自己实例化后一次性地创建由 model 决定的所有 Item,这在某些情况下可能会被认为效率低下。比如 model 提供了 10000 个数据,Repeater 就实例化 10000 个 delegate 组件。如果你对这个敏感,可以使用 ListView,它创建 Item 是渐进式的,一开始只 创建少量的 Item,足够界面显示,当用户滚动 ListView,那些原本不可见的 Item 要被显示时 才会适时创建。
model 属性可以取下列值:
- 数字
- 字符串列表
- 对象列表
- ListModel 等常见的 model
咱们一个个来看吧。
model 为数字
model 为数字时指示 Repeater 创建特定数量的组件,此时在 delegate 组件内可以访问 index 属性。
简单示例 repeater_number.qml:
import QtQuick 2.2
import QtQuick.Layouts 1.1
Rectangle {
400
height: 200
color: "#EEEEEE"
RowLayout {
anchors.fill: parent
spacing: 4
Repeater {
model: 8
Rectangle {
46
height: 30
color: "steelblue"
Text {
anchors.fill: parent
color: "black"
font.pointSize: 14
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
text: index
}
}
}
}
}
model 取值 8,delegate 是内嵌一个 Text 对象的 Rectangle 对象,Text 对象显示索引。我使用 RowLayout 作为 Repeater 的 parent。效果图如下所示:
model为字符串列表
当使用字符串列表作为 model 时,Repeater 创建的 Item 数量由列表长度决定,在 delegate 内可以通过 modelData 访问字符串对象。
import QtQuick 2.2
import QtQuick.Layouts 1.1
Rectangle {
300
height: 200
color: "#EEEEEE"
Row {
anchors.centerIn: parent
spacing: 8
Repeater {
model: ["Hello", "Qt", "Quick"]
Text {
color: "blue"
font.pointSize: 18
font.bold: true
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
text: modelData
}
}
}
}
这里使用 Row 作为 Repeater 的 parent。delegate 非常简单,就是个 Text 对象。使用 qmlscene 加载 repeater_stringlist.qml,效果图如下所示:
model为对象列表
使用对象列表作为 model 与使用字符串列表类似,只是 modelData 代表 model 中的对象: 直接看 repeater_objects.qml:
import QtQuick 2.2
Rectangle {
320
height: 200
color: "#EEEEEE"
Column {
anchors.fill: parent
anchors.margins: 4
spacing: 4
Repeater {
model: [
{"name":"Zhang San", "mobile":"13888888888"},
{"name":"Wang Er", "mobile":"13999999999"},
{"name":"Liu Wu", "mobile":"15866666666"},
]
Row {
height: 30
Text{
100
color: "blue"
font.pointSize: 13
font.bold: true
verticalAlignment: Text.AlignVCenter
text: modelData.name
}
Text{
200
font.pointSize: 13
verticalAlignment: Text.AlignVCenter
text: modelData.mobile
}
}
}
}
}
注意,在 delegate 内将 modelData 作为对象使用,直接访问它的属性,效果图如下所示:
model为ListModel
model 也可以是 ListModel 或者 QAbstractltemModel 的派生类。此时在 delegate 内可以通过 role-name 访问 model 内的数据。
repeaterlistmodel.qml 展示了如何使用 ListModel:
import QtQuick 2.2
Rectangle {
300
height: 200
color: "#EEEEEE"
Column {
anchors.fill: parent
anchors.margins: 4
spacing: 4
Repeater {
model: ListModel {
ListElement{
name: "MI4"
cost: "1999"
manufacturer: "Xiaomi"
}
ListElement{
name: "MX4"
cost: "1999"
manufacturer: "Meizu"
}
ListElement{
name: "iPhone6"
cost: "5500"
manufacturer: "Apple"
}
ListElement{
name: "C199"
cost: "1599"
manufacturer: "Huawei"
}
}
Row {
height: 30
Text{
120
color: "blue"
font.pointSize: 14
font.bold: true
verticalAlignment: Text.AlignVCenter
text: name
}
Text{
100
font.pointSize: 14
verticalAlignment: Text.AlignVCenter
text: cost
}
Text{
100
font.pointSize: 12
verticalAlignment: Text.AlignVCenter
text: manufacturer
}
}
}
}
}
效果图如下所示: