4.8 用于定位的元素
有許多用于定位 Item 的 QML 元素。這些被稱為定位器,并且在 QtQuick 模塊中提供了以下內(nèi)容:Row、Column、Grid 和 Flow。我們會(huì)在接下來(lái)介紹它們的顯示內(nèi)容的效果。
** 注意: **
在討論細(xì)節(jié)之前,讓我介紹一些輔助元素。紅色,藍(lán)色,綠色,淺色和深色的方塊。每個(gè)組件都包含一個(gè) 48 x 48 像素的彩色矩形。這里是 RedSquare 的源代碼:
// RedSquare.qml
import QtQuick 2.5
Rectangle {
width: 48
height: 48
color: "#ea7025"
border.color: Qt.lighter(color)
}
請(qǐng)注意使用 Qt.lighter(color) 來(lái)產(chǎn)生較淺的邊框顏色。在下一個(gè)示例中,我們將使用這些幫助器,使源代碼更加緊湊和易讀。請(qǐng)記住,每個(gè)矩形的初始值為 48 x 48 像素。
Column (列)元素將子項(xiàng)安排到列中,將它們堆疊在一起。spacing (間距)屬性可用于分隔每個(gè)子元素之間的距離。

// column.qml
import QtQuick 2.5
DarkSquare {
id: root
width: 120
height: 240
Column {
id: row
anchors.centerIn: parent
spacing: 8
RedSquare { }
GreenSquare { width: 96 }
BlueSquare { }
}
}
Row 元素將它的子項(xiàng)放在一起,從左到右,或者從右到左排列,這取決于 layoutDirection 屬性。同樣,spacing 屬性是用來(lái)分隔子項(xiàng)的。

// row.qml
import QtQuick 2.5
BrightSquare {
id: root
width: 400; height: 120
Row {
id: row
anchors.centerIn: parent
spacing: 20
BlueSquare { }
GreenSquare { }
RedSquare { }
}
}
Grid 元素在網(wǎng)格中安排其子元素,通過(guò)設(shè)置 rows 和 columns 屬性,可以限制行或列的數(shù)量。如果僅設(shè)置它們中的任何一個(gè),另一個(gè)是根據(jù)子條目的數(shù)量來(lái)計(jì)算的。例如,將行設(shè)置為 3 并添加 6 個(gè)子項(xiàng)將會(huì)導(dǎo)致 2 列。屬性 flow 和 layoutDirection 用于控制將條目添加到網(wǎng)格的順序,而 spacing 控制子項(xiàng)的分隔空間。

// grid.qml
import QtQuick 2.5
BrightSquare {
id: root
width: 160
height: 160
Grid {
id: grid
rows: 2
columns: 2
anchors.centerIn: parent
spacing: 8
RedSquare { }
RedSquare { }
RedSquare { }
RedSquare { }
}
}
最后的定位器是 flow。它在流中添加子項(xiàng)。流的方向是使用 flow 和 layoutDirection 來(lái)控制的。它可以從側(cè)面或者從頂部到底部。它也可以從左向右或相反方向運(yùn)行。當(dāng)這些項(xiàng)被添加到流中時(shí),它們會(huì)被包裝成新的行或列。為了讓一個(gè)流工作,它必須有一個(gè)寬度或一個(gè)高度??梢灾苯釉O(shè)置,也可以通過(guò)設(shè)置錨布局來(lái)實(shí)現(xiàn)。

// flow.qml
import QtQuick 2.5
BrightSquare {
id: root
width: 160
height: 160
Flow {
anchors.fill: parent
anchors.margins: 20
spacing: 20
RedSquare { }
BlueSquare { }
GreenSquare { }
}
}
經(jīng)常在定位器使用的一個(gè)元素是 Repeater。它的工作原理類似于 for 循環(huán),并在模型上迭代。在最簡(jiǎn)單的情況下,模型只是提供循環(huán)數(shù)量的一個(gè)值。

// repeater.qml
import QtQuick 2.5
DarkSquare {
id: root
width: 252
height: 252
property variant colorArray: ["#00bde3", "#67c111", "#ea7025"]
Grid{
anchors.fill: parent
anchors.margins: 8
spacing: 4
Repeater {
model: 16
Rectangle {
width: 56; height: 56
property int colorIndex: Math.floor(Math.random()*3)
color: root.colorArray[colorIndex]
border.color: Qt.lighter(color)
Text {
anchors.centerIn: parent
color: "#f0f0f0"
text: "Cell " + index
}
}
}
}
}
在這個(gè) Repeater 示例中,我們使用了一些新的魔法。我們定義自己的顏色屬性,我們用它作為一組顏色。Repeater 創(chuàng)建了一系列的矩形(由模型定義的 16 個(gè)矩形)。對(duì)于每個(gè)循環(huán),他創(chuàng)建一個(gè)矩形,由 Repeater 的子定義。在矩形中,我們使用 JS 數(shù)學(xué)函數(shù) Math.floor(Math.random()*3) 來(lái)隨機(jī)選擇顏色。這給了我們一個(gè)從 0 到 2 的隨機(jī)數(shù)字。我們用來(lái)從顏色數(shù)組中選擇顏色。正如前面提到的,JavaScript 是 Qt Quick 的核心部分,因此我們可以自由地使用這些標(biāo)準(zhǔn)庫(kù)。
Repeater 將 index 屬性注入到 Repeater 中。它包含當(dāng)前的循環(huán)索引。(0、1、...、15)。我們可以使用這個(gè)來(lái)根據(jù) index 來(lái)做出自己的決定,或者在我們的例子中使用文本元素來(lái)可視化當(dāng)前的 index。
** 注意: **
更高級(jí)的模型和動(dòng)態(tài)視圖的動(dòng)態(tài)視圖的更高級(jí)的處理被包含在模型視圖(model-view)的章節(jié)中。當(dāng)提供少量靜態(tài)數(shù)據(jù)時(shí),最好使用 Repeater 。
4.9 對(duì)元素進(jìn)行布局
QML 提供了一種靈活的方式用來(lái)錨定元素。錨定的概念是元素基本屬性的一部分,可用于所有可視的 QML 元素。錨的作用類似于合同,比幾何變化更強(qiáng)。錨是一種相對(duì)的布局方法,我們總是需要一個(gè)相關(guān)的元素來(lái)進(jìn)行錨定。

每個(gè)元素有 6 個(gè)主錨線(top、bottom、left、right、horizontalCenter、verticalCenter)。另外還有文本元素中文本的基線錨。每個(gè)錨點(diǎn)都有一個(gè)偏移量。在 top、bottom、left 和 right ,它們被稱為邊距。對(duì)于水平中心,垂直中心和基線,它們被稱為偏移量。

- 元素填充了父元素:
GreenSquare {
BlueSquare {
width: 12
anchors.fill: parent
anchors.margins: 8
text: '(1)'
}
}
- 元素與父元素左側(cè)保持一致:
GreenSquare {
BlueSquare {
width: 48
y: 8
anchors.left: parent.left
anchors.leftMargin: 8
text: '(2)'
}
}
- 元素的左側(cè)與父元素右側(cè)對(duì)齊:
GreenSquare {
BlueSquare {
width: 48
anchors.left: parent.right
text: '(3)'
}
}
- 中心對(duì)齊元素。Blue1 的是水平居中的父結(jié)點(diǎn)。Blue2 也是水平居中,但是顯示在 Blue1 的上面,這是因?yàn)樗捻敳颗c Blue1 的底部對(duì)齊:
GreenSquare {
BlueSquare {
id: blue1
width: 48; height: 24
y: 8
anchors.horizontalCenter: parent.horizontalCenter
}
BlueSquare {
id: blue2
width: 72; height: 24
anchors.top: blue1.bottom
anchors.topMargin: 4
anchors.horizontalCenter: blue1.horizontalCenter
text: '(4)'
}
}
- 元素以父元素為中心:
GreenSquare {
BlueSquare {
width: 48
anchors.centerIn: parent
text: '(5)'
}
}
- 元素的中心是使用相對(duì)于父元素的水平和垂直中心,并且相對(duì)父元素向左偏移 12 像素:
GreenSquare {
BlueSquare {
width: 48
anchors.horizontalCenter: parent.horizontalCenter
anchors.horizontalCenterOffset: -12
anchors.verticalCenter: parent.verticalCenter
text: '(6)'
}
}
** 注意: **
在實(shí)際的代碼中我們的方塊已經(jīng)被增強(qiáng),以支持拖動(dòng)。試試拖動(dòng)一些方塊。我們將發(fā)現(xiàn) (1) 不能被拖動(dòng),因?yàn)樗诲^定在父對(duì)象的所有的邊上,當(dāng)然我們也可以拖動(dòng) (1) 的父對(duì)象,因?yàn)樗緵](méi)有進(jìn)行錨定。(2) 可以垂直拖動(dòng),因?yàn)樗淖筮吺清^定的。類似的情況也適用于 (3)。(4) 只能垂直拖動(dòng),因?yàn)閮蓚€(gè)正方形都是水平居中。(5) 以父元素為中心,因此不能被拖動(dòng),類似于 (7)。拖動(dòng)一個(gè)元素就意味著改變它們的 x、y 位置。由于錨固定比 x、y 的幾何變化更強(qiáng),所以拖拽被錨定線所限制。當(dāng)后面我們討論動(dòng)畫(huà)時(shí),我們也將會(huì)看到這個(gè)效果。
本文參考鏈接:Quick Starter