qml佈局-描點佈局anchors

上一章我們介紹了 QML 中用於定位的幾種元素,被稱爲定位器。除了定位器,QML 還提供了另外一種用於佈局的機制。我們將這種機制成爲錨點(anchor)。錨點允許我們靈活地設置兩個元素的相對位置。它使兩個元素之間形成一種類似於錨的關係,也就是兩個元素之間形成一個固定點。錨點的行爲類似於一種鏈接,它要比單純地計算座標改變更強。由於錨點描述的是相對位置,所以在使用錨點時,我們必須指定兩個元素,聲明其中一個元素相對於另外一個元素。錨點是Item元素的基本屬性之一,因而適用於所有 QML 可視元素。

一個元素有 6 個主要的錨點的定位線,如下圖所示:
QML 錨點
這 6 個定位線分別是:top、bottom、left、right、horizontalCenter和verticalCenter。對於Text元素,還有一個baseline錨點。每一個錨點定位線都可以結合一個偏移的數值。其中,top、bottom、left和right稱爲外邊框;horizontalCenter、verticalCenter和baseline稱爲偏移量。

下面,我們使用例子來說明這些錨點的使用。首先,我們需要重新定義一下上一章使用過的BlueRectangle組件:
BlueRectangle
import QtQuick 2.0

Rectangle {
width: 48
height: 48
color: “blue”
border.color: Qt.lighter(color)

MouseArea {
    anchors.fill: parent
    drag.target: parent
}

}
1
2
3
4
5
6
7
8
9
10
11
12
13

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組件。

接下來看第一個例子:

QML anchors.fill

代碼如下:
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
    }
}

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

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。

第二個例子:

QML anchors.left

代碼如下:
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
    }
}

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

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 的位置上下移動,這是由於我們設置了錨點的緣故。正如我們前面提到過的,錨點要比單純地計算座標改變的效果更強,更優先。

第三個例子:
QML anchors.left parent.right
代碼如下:
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
    }
}

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

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,也就是將組件錨點的左邊線設置爲父組件的右邊線。效果即如上圖所示。當我們拖動組件時,依然只能上下移動。

下一個例子:
QML anchors.horizontalCenter

代碼如下:
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
    }
}

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

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的相對位置始終不變,因爲我們已經明確指定了這種相對位置,而二者可以像一個整體似的同時上下移動(因爲我們沒有指定其中任何一個的上下邊距與父組件的關係)。

另外一個例子:
QML anchors.centerIn
代碼如下所示:
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
    }
}

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

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將藍色矩形的中心固定在父組件的中心。由於我們已經指明是中心,所以也不能拖動這個藍色矩形。

最後一個例子:
QML anchors.horizontalCenter verticalCenter

代碼如下:
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
    }
}

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

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 中定位器和錨點的概念。看起來這些元素和機制都很簡單,但是,通過有機地結合,足以靈活應對更復雜的場景。我們所要做的就是不斷熟悉、深化對這些定位佈局技術的理解。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章