概述
使用Qt做过UI的一定对QHBoxLayout, QVBoxLayout, 和QGridLayout这三个最重要也最常使用的layout managers非常熟悉。那么在QML中又是如何控制和管理UI布局的呢?那么我们这篇文章就为大家介绍这些基础知识。
首先,QML同样允许大家使用硬编码的方式将位置数值直接写到代码中,但是这样做首先难以适应UI的调整,其次代码维护起来也很困难。因此我们不推荐这样做。推荐大家使用的是以下三种布局管理器:Row,、Column、Grid,以及使用Anchor进行布局。
Row
QML 中的 Row 元素会将其子控件都排列在同一行,相互不重叠。我们还可以使用它的spacing 属性来定义子控件之间的距离。比如下列代码就会产生如图所示的效果:
Row {
$ l7 r4 j9 V! N. h( n- ?) }
spacing:
2
" F/ Q1 G* v- G9 h( U* s5 w8 A! L Rectangle { color:
"red"; width:
50; height:
50 }
. Z0 b- a6 }- [ ` Rectangle { color:
"green"; width:
20; height:
50 }
2 @# Y& l, A! a4 ?! N6 P/ p
Rectangle { color:
"blue"; width:
50; height:
20 }
+ _* @8 D$ u7 ~
}
Column
QML 中的 Column元素会将其子控件都排列在同一列,相互不重叠。我们还可以使用它的spacing 属性来定义子控件之间的距离。比如下列代码就会产生如图所示的效果:
Column {
3 ]5 ?0 E6 K( S4 G) s
spacing:
2
. K$ z4 _0 \% Y0 f" j# t, } Rectangle { color:
"red"; width:
50; height:
50 }
' T$ y3 Z5 o2 K" b- Y8 i Rectangle { color:
"green"; width:
20; height:
50 }
( n8 s7 x* g+ Q% o8 f4 o Rectangle { color:
"blue"; width:
50; height:
20 }
7 l( K. D# m5 ?}
Grid
QML 中的 Grid元素会将其子控件都均匀地排列在一个网格内,相互不重叠,每一个子控件都被放置在一个网格单元的(0,0)位置,也就是左上角。Grid的rows 和columns属性定义网格的行数和列数,列数默认是4。我们还可以使用Grid的spacing 属性来定义网格单元之间的距离,这里注意水平和垂直方向的spacing都是一样的。比如下列代码就会产生如图所示的效果:
Grid {
4 {$ V( v6 G h. Y9 z
columns:
3
" n: J2 i! ~7 \/ C+ m$ e2 |/ R3 n: [ spacing:
2
" s) c9 Q" H6 q; r. d7 z' E4 c Rectangle { color:
"red"; width:
50; height:
50 }
! u& [9 w+ s9 m( _ Rectangle { color:
"green"; width:
20; height:
50 }
# @" Z8 O% |8 I% Q
Rectangle { color:
"blue"; width:
50; height:
20 }
. z9 {$ H& j8 D; P w Rectangle { color:
"cyan"; width:
50; height:
50 }
t6 Q+ B. d" G5 K. |9 D Rectangle { color:
"magenta"; width:
10; height:
10 }
2 F; v$ K3 U& @# h. Q! f1 \}
0 k6 M; I3 ?( Y; z6 o- N! P* m, w混合应用
我们还可以将Grid、Row 和 Column 进行混合应用。比如下面的代码会产生如图所示的效果:
Column {
' F) [6 a1 ]) m) q7 u3 K9 _ spacing:
29 ^. w2 n2 \/ W
Rectangle { color:
"red"; width:
50; height:
50 }
5 ]' [' |1 [2 }, @ Row {
3 A$ H: M$ V1 g spacing:
2' P* \8 {2 j; t6 t+ i7 M
Rectangle { color:
"yellow"; width:
50; height:
50 }
l# t$ @% t* ?8 }3 Y7 s( u Rectangle { color:
"black"; width:
20; height:
50 }
: _ A' |& F1 c, c1 P4 Y" h1 K Rectangle { color:
"blue"; width:
50; height:
20 }
b$ Y( p% `% }, W V- H& A }
- b2 R- L- A# E' F2 L
Rectangle { color:
"green"; width:
20; height:
50 }
; V4 v9 c1 n! A) f g$ _5 e1 K8 n}
% c! ]% K" Y/ g. q
Anchor
以上方法进行排列是不重叠的,而anchor通俗的说是当前图形相对于某一图形的位置(可重叠)
每一个item 都可以被认为具有 7 条隐藏的“anchor lines":left、 horizontalCenter、 right、 top、 verticalCenter、baseline、以及bottom,如下图所示:
····
其中baseline是指的文本所在的线,在上图中并未标出,如果item没有文字的话baselinw就和top的位置是相同的。
8 H# s$ s$ y! H# W/ _( g7 B3 ?除此之外,Anchor系统还提供了margins 和offsets。margins 是指一个item和外界之间所留有的空间,而offsets 则可以通过使用 center anchor lines来进行布局。如下图所示
·····
使用 QML anchoring系统,我们可以定义不同items之间的anchor lines之间的关系。例如:
Rectangle { id: rect1; ... }& p& W* J4 P- ]# T3 R$ S. b
Rectangle { id: rect2; anchors.left: rect1.right; anchors.leftMargin: 5; ... }
·····
我们还可以使用多个anchors:
Rectangle { id: rect1; ... }
0 g5 ~& J; h/ h* Q: k- [, y1 hRectangle { id: rect2; anchors.left: rect1.right; anchors.top: rect1.bottom; ... }
·····
通过定义多个水平或垂直的anchors,我们还可以控制item的大小,例如:
Rectangle { id: rect1; x: 0; ... }
- g2 V& {' ~' E5 rRectangle { id: rect2; anchors.left: rect1.right; anchors.right: rect3.left; ... }
/ p7 R. c& P, L* W; DRectangle { id: rect3; x: 150; ... }
·····
注意:出于效率方面的考虑,我们只允许对一个item的邻居和之接父亲使用anchor定义。比如下面的定义是不合法的:
# [* K3 ^9 @5 D5 p& d/ o% BItem {
6 d( q7 n* @9 X# v id: group1
7 A8 U- @, z# V5 U! z& a2 ~" H Rectangle { id: rect1; ... }/ T3 p4 C w6 ^6 a) v; y
}
) |5 o% U4 }3 E/ Z; }Item {
, C* W4 t) J& G* _ id: group2
; S2 C$ w- O4 p( r Rectangle { id: rect2; anchors.left: rect1.right; ... } // invalid anchor!
, L2 v* b) {1 P1 ]}* |# b8 S \( X3 r