簡介
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 {
width: 400
height: 200
color: "#EEEEEE"
RowLayout {
anchors.fill: parent
spacing: 4
Repeater {
model: 8
Rectangle {
width: 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 {
width: 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 {
width: 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{
width: 100
color: "blue"
font.pointSize: 13
font.bold: true
verticalAlignment: Text.AlignVCenter
text: modelData.name
}
Text{
width: 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 {
width: 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{
width: 120
color: "blue"
font.pointSize: 14
font.bold: true
verticalAlignment: Text.AlignVCenter
text: name
}
Text{
width: 100
font.pointSize: 14
verticalAlignment: Text.AlignVCenter
text: cost
}
Text{
width: 100
font.pointSize: 12
verticalAlignment: Text.AlignVCenter
text: manufacturer
}
}
}
}
}
效果圖如下所示: