#(81):元素布局
上一章我們介紹了 QML?中用于定位的幾種元素,被稱為定位器。除了定位器,QML?還提供了另外一種用于布局的機制。我們將這種機制成為錨點(anchor)。錨點允許我們靈活地設置兩個元素的相對位置。它使兩個元素之間形成一種類似于錨的關系,也就是兩個元素之間形成一個固定點。錨點的行為類似于一種鏈接,它要比單純地計算坐標改變更強。由于錨點描述的是相對位置,所以在使用錨點時,我們必須指定兩個元素,聲明其中一個元素相對于另外一個元素。錨點是`Item`元素的基本屬性之一,因而適用于所有 QML 可視元素。
一個元素有 6 個主要的錨點的定位線,如下圖所示:
[](http://files.devbean.net/images/2014/02/qml-anchors.png)
這 6 個定位線分別是:`top`、`bottom`、`left`、`right`、`horizontalCenter`和`verticalCenter`。對于`Text`元素,還有一個`baseline`錨點。每一個錨點定位線都可以結合一個偏移的數值。其中,`top`、`bottom`、`left`和`right`稱為外邊框;`horizontalCenter`、`verticalCenter`和`baseline`稱為偏移量。
下面,我們使用例子來說明這些錨點的使用。首先,我們需要重新定義一下上一章使用過的`BlueRectangle`組件:
~~~
import QtQuick 2.0
Rectangle {
width: 48
height: 48
color: "blue"
border.color: Qt.lighter(color)
MouseArea {
anchors.fill: parent
drag.target: parent
}
}
~~~
簡單來說,我們在`BlueRectangle`最后增加了一個`MouseArea`組件。前面的章節中,我們簡單使用了這個組件。顧名思義,這是一個用于處理鼠標事件的組件。之前我們使用了它處理鼠標點擊事件。這里,我們使用了其拖動事件。`anchors.fill: parent`一行的含義馬上就會解釋;`drag.target: parent`則說明拖動目標是`parent`。我們的拖動對象是`MouseArea`的父組件,也就是`BlueRectangle`組件。
接下來看第一個例子:
[](http://files.devbean.net/images/2014/02/qml-anchors-fill.png)
代碼如下:
~~~
import QtQuick 2.0
Rectangle {
id: root
width: 220
height: 220
color: "black"
GreenRectangle {
x: 10
y: 10
width: 100
height: 100
BlueRectangle {
width: 12
anchors.fill: parent
anchors.margins: 8
}
}
}
~~~
在這個例子中,我們使用`anchors.fill`設置內部藍色矩形的錨點為填充(fill),填充的目的對象是`parent`;填充邊距是 8px。注意,盡管我們設置了藍色矩形寬度為 12px,但是因為錨點的優先級要高于寬度屬性設置,所以藍色矩形的實際寬度是 100px – 8px – 8px = 84px。
第二個例子:
[](http://files.devbean.net/images/2014/02/qml-anchors-left.png)
代碼如下:
~~~
import QtQuick 2.0
Rectangle {
id: root
width: 220
height: 220
color: "black"
GreenRectangle {
x: 10
y: 10
width: 100
height: 100
BlueRectangle {
width: 48
y: 8
anchors.left: parent.left
anchors.leftMargin: 8
}
}
}
~~~
這次,我們使用`anchors.left`設置內部藍色矩形的錨點為父組件的左邊線(parent.left);左邊距是 8px。另外,我們可以試著拖動藍色矩形,看它的移動方式。在我們拖動時,藍色矩形只能沿著距離父組件左邊 8px 的位置上下移動,這是由于我們設置了錨點的緣故。正如我們前面提到過的,錨點要比單純地計算坐標改變的效果更強,更優先。
第三個例子:
[](http://files.devbean.net/images/2014/02/qml-anchors-left-right.png)
代碼如下:
~~~
import QtQuick 2.0
Rectangle {
id: root
width: 220
height: 220
color: "black"
GreenRectangle {
x: 10
y: 10
width: 100
height: 100
BlueRectangle {
width: 48
anchors.left: parent.right
}
}
}
~~~
這里,我們修改代碼為`anchors.left: parent.right`,也就是將組件錨點的左邊線設置為父組件的右邊線。效果即如上圖所示。當我們拖動組件時,依然只能上下移動。
下一個例子:
[](http://files.devbean.net/images/2014/02/qml-anchors-horizontalcenter.png)
代碼如下:
~~~
import QtQuick 2.0
Rectangle {
id: root
width: 220
height: 220
color: "black"
GreenRectangle {
x: 10
y: 10
width: 100
height: 100
BlueRectangle {
id: blue1
width: 48; height: 24
y: 8
anchors.horizontalCenter: parent.horizontalCenter
}
BlueRectangle {
id: blue2
width: 72; height: 24
anchors.top: blue1.bottom
anchors.topMargin: 4
anchors.horizontalCenter: blue1.horizontalCenter
}
}
}
~~~
這算是一個稍微復雜的例子。這里有兩個藍色矩形:`blue1`和`blue2`。`blue1`的錨點水平中心線設置為父組件的水平中心;`blue2`的錨點上邊線相對于`blue1`的底部,其中邊距為 4px,另外,我們還增加了一個水平中線為`blue1`的水平中線。這樣,`blue1`相對于父組件,`blue2`相對于`blue1`,這樣便決定了三者之間的相對關系。當我們拖動藍色矩形時可以發現,`blue1`和`blue2`的相對位置始終不變,因為我們已經明確指定了這種相對位置,而二者可以像一個整體似的同時上下移動(因為我們沒有指定其中任何一個的上下邊距與父組件的關系)。
另外一個例子:
[](http://files.devbean.net/images/2014/02/qml-anchors-centerin.png)
代碼如下所示:
~~~
import QtQuick 2.0
Rectangle {
id: root
width: 220
height: 220
color: "black"
GreenRectangle {
x: 10
y: 10
width: 100
height: 100
BlueRectangle {
width: 48
anchors.centerIn: parent
}
}
}
~~~
與第一個例子類似,我們使用的是`anchors.centerIn: parent`將藍色矩形的中心固定在父組件的中心。由于我們已經指明是中心,所以也不能拖動這個藍色矩形。
最后一個例子:
[](http://files.devbean.net/images/2014/02/qml-anchors-hc-vc.png)
代碼如下:
~~~
import QtQuick 2.0
Rectangle {
id: root
width: 220
height: 220
color: "black"
GreenRectangle {
x: 10
y: 10
width: 100
height: 100
BlueRectangle {
width: 48
anchors.horizontalCenter: parent.horizontalCenter
anchors.horizontalCenterOffset: -12
anchors.verticalCenter: parent.verticalCenter
}
}
}
~~~
上一個例子中,`anchors.centerIn: parent`可以看作等價于`anchors.horizontalCenter: parent.horizontalCenter`和`anchors.verticalCenter: parent.verticalCenter`。而這里,我們設置了`anchors.horizontalCenterOffset`為 -12,也就是向左偏移 12px。當然,我們也可以在`anchors.centerIn: parent`的基礎上增加`anchors.horizontalCenterOffset`的值,二者是等價的。由于我們在這里指定的相對位置已經很明確,拖動也是無效的。
至此,我們簡單介紹了 QML?中定位器和錨點的概念。看起來這些元素和機制都很簡單,但是,通過有機地結合,足以靈活應對更復雜的場景。我們所要做的就是不斷熟悉、深化對這些定位布局技術的理解。
- (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(續)