#(84):Repeater
[前面的章節](http://www.devbean.net/2013/01/qt-study-road-2-model-view/)我們介紹過模型視圖。這是一種數據和顯示相分離的技術,在 Qt 中有著非常重要的地位。在 QtQuick 中,數據和顯示的分離同樣也是利用這種“模型-視圖”技術實現的。對于每一個視圖,數據元素的可視化顯示交給代理完成。與 Qt/C++ 類似,QtQuick 提供了一系列預定義的模型和視圖。本章開始,我們著重介紹這部分內容。這部分內容主要來自[http://qmlbook.org/ch06/index.html](http://qmlbook.org/ch06/index.html),在此表示感謝。
由于 QtQuick 中的模型視圖的基本概念同[前面的章節](http://www.devbean.net/2013/01/qt-study-road-2-model-view/)沒有本質的區別,所以這里不再贅述這部分內容。
將數據從表現層分離的最基本方法是使用`Repeater`元素。`Repeater`元素可以用于顯示一個數組的數據,并且可以很方便地在用戶界面進行定位。`Repeater`的模型范圍很廣:從一個整型到網絡數據,均可作為其數據模型。
`Repeater`最簡單的用法是將一個整數作為其`model`屬性的值。這個整型代表`Repeater`所使用的模型中的數據個數。例如下面的代碼中,`model: 10`代表`Repeater`的模型有 10 個數據項。
~~~
import QtQuick 2.2
Column {
spacing: 2
Repeater {
model: 10
Rectangle {
width: 100
height: 20
radius: 3
color: "lightBlue"
Text {
anchors.centerIn: parent
text: index
}
}
}
}
~~~
現在我們設置了 10 個數據項,然后定義一個`Rectangle`進行顯示。每一個`Rectangle`的寬度和高度分別為 100px 和 20px,并且有圓角和淺藍色背景。`Rectangle`中有一個`Text`元素為其子元素,`Text`文本值為當前項的索引。代碼運行結果如下:
[](http://files.devbean.net/images/2014/06/repeater-demo.png)
雖然指定模型項的個數很簡單,但實際用處不大。`Repeater`還支持更復雜的方式,例如,把一個 JavaScript 數組作為模型。JavaScript 數組元素可以是任意類型:字符串、數字或對象。在下面的例子中,我們將一個字符串數組作為`Repeater`的模型。我們當然可以使用`index`獲得當前索引,同時,我們也可以使用`modelData`訪問到數組中的每一個元素的值:
~~~
import QtQuick 2.2
Column {
spacing: 2
Repeater {
model: ["Enterprise", "Colombia", "Challenger", "Discovery", "Endeavour", "Atlantis"]
Rectangle {
width: 100
height: 20
radius: 3
color: "lightBlue"
Text {
anchors.centerIn: parent
text: index +": "+modelData
}
}
}
}
~~~
代碼運行結果如下:

由于能夠使用 JavaScript 數組作為`Repeater`的模型,而 JavaScript 數組能夠以對象作為其元素類型,因而`Repeater`就可以處理復雜的數據項,比如帶有屬性的對象。這種情況其實更為常見。相比普通的 JavaScript 對象,更常用的是`ListElement`類型。類似普通 JavaScript 對象,每一個`ListElement`可以有任意屬性。例如下面的代碼示例中,每一個數據項都有一個名字和外觀顏色。
~~~
import QtQuick 2.2
Column {
spacing: 2
Repeater {
model: ListModel {
ListElement { name: "Mercury"; surfaceColor: "gray" }
ListElement { name: "Venus"; surfaceColor: "yellow" }
ListElement { name: "Earth"; surfaceColor: "blue" }
ListElement { name: "Mars"; surfaceColor: "orange" }
ListElement { name: "Jupiter"; surfaceColor: "orange" }
ListElement { name: "Saturn"; surfaceColor: "yellow" }
ListElement { name: "Uranus"; surfaceColor: "lightBlue" }
ListElement { name: "Neptune"; surfaceColor: "lightBlue" }
}
Rectangle {
width: 100
height: 20
radius: 3
color: "lightBlue"
Text {
anchors.centerIn: parent
text: name
}
Rectangle {
anchors.left: parent.left
anchors.verticalCenter: parent.verticalCenter
anchors.leftMargin: 2
width: 16
height: 16
radius: 8
border.color: "black"
border.width: 1
color: surfaceColor
}
}
}
}
~~~
運行結果如下圖所示:
[](http://files.devbean.net/images/2014/06/repeater-listelement.png)
`ListElement`的每個屬性都被`Repeater`綁定到實例化的顯示項。正如上面代碼中顯示的那樣,這意味著每一個用于顯示數據的`Rectangle`作用域內都可以訪問到`ListElement`的`name`和`surfaceColor`屬性。
像上面幾段代碼中,`Repeater`的每一個數據項都使用一個`Rectangle`渲染。事實上,這是由于`Repeater`具有一個`delegate`的默認屬性,由于`Rectangle`沒有顯式賦值給任何一個屬性,因此它直接成為默認屬性`delegate`的值,所以才會使用`Rectangle`渲染。理解了這一點,我們就可以寫出具有顯式賦值的代碼:
~~~
import QtQuick 2.2
Column {
spacing: 2
Repeater {
model: 10
delegate: Rectangle {
width: 100
height: 20
radius: 3
color: "lightBlue"
Text {
anchors.centerIn: parent
text: index
}
}
}
}
~~~
實際上,這段代碼與前面提到的是等價的。
- (1)序
- (2)Qt 簡介
- (3)Hello, world!
- (4)信號槽
- (5)自定義信號槽
- (6)Qt 模塊簡介
- (7)MainWindow 簡介
- (8)添加動作
- (9)資源文件
- (10)對象模型
- (11)布局管理器
- (12)菜單欄、工具欄和狀態欄
- (13)對話框簡介
- (14)對話框數據傳遞
- (15)標準對話框 QMessageBox
- (16)深入 Qt5 信號槽新語法
- (17)文件對話框
- (18)事件
- (19)事件的接受與忽略
- (21)事件過濾器
- (22)事件總結
- (23)自定義事件
- (24)Qt 繪制系統簡介
- (25)畫刷和畫筆
- (26)反走樣
- (27)漸變
- (28)坐標系統
- (29)繪制設備
- (30)Graphics View Framework
- (31)貪吃蛇游戲(1)
- (32)貪吃蛇游戲(2)
- (33)貪吃蛇游戲(3)
- (34)貪吃蛇游戲(4)
- (35)文件
- (36)二進制文件讀寫
- (37)文本文件讀寫
- (38)存儲容器
- (39)遍歷容器
- (40)隱式數據共享
- (41)model/view 架構
- (42)QListWidget、QTreeWidget 和 QTableWidget
- (43)QStringListModel
- (44)QFileSystemModel
- (45)模型
- (46)視圖和委托
- (47)視圖選擇
- (48)QSortFilterProxyModel
- (49)自定義只讀模型
- (50)自定義可編輯模型
- (51)布爾表達式樹模型
- (52)使用拖放
- (53)自定義拖放數據
- (54)剪貼板
- (55)數據庫操作
- (56)使用模型操作數據庫
- (57)可視化顯示數據庫數據
- (58)編輯數據庫外鍵
- (59)使用流處理 XML
- (60)使用 DOM 處理 XML
- (61)使用 SAX 處理 XML
- (62)保存 XML
- (63)使用 QJson 處理 JSON
- (64)使用 QJsonDocument 處理 JSON
- (65)訪問網絡(1)
- (66)訪問網絡(2)
- (67)訪問網絡(3)
- (68)訪問網絡(4)
- (69)進程
- (70)進程間通信
- (71)線程簡介
- (72)線程和事件循環
- (73)Qt 線程相關類
- (74)線程和 QObject
- (75)線程總結
- (76)QML 和 QtQuick 2
- (77)QML 語法
- (78)QML 基本元素
- (79)QML 組件
- (80)定位器
- (81)元素布局
- (82)輸入元素
- (83)Qt Quick Controls
- (84)Repeater
- (85)動態視圖
- (86)視圖代理
- (87)模型-視圖高級技術
- (88)Canvas
- (89)Canvas(續)