概述
使用Qt做过UI的一定对QHBoxLayout, QVBoxLayout, 和QGridLayout这三个最重要也最常使用的layout managers非常熟悉。那么在QML中又是如何控制和管理UI布局的呢?那么我们这篇文章就为大家介绍这些基础知识。
首先,QML同样允许大家使用硬编码的方式将位置数值直接写到代码中,但是这样做首先难以适应UI的调整,其次代码维护起来也很困难。因此我们不推荐这样做。推荐大家使用的是以下三种布局管理器:Row,、Column、Grid,以及使用Anchor进行布局。
Row
QML 中的 Row 元素会将其子控件都排列在同一行,相互不重叠。我们还可以使用它的spacing 属性来定义子控件之间的距离。比如下列代码就会产生如图所示的效果:
Row {
, E. I( F, b. z. z1 B
spacing:
2
8 W& {: L, k* X Rectangle { color:
"red"; width:
50; height:
50 }
8 i6 {- @! l! P' g4 W9 T0 A Rectangle { color:
"green"; width:
20; height:
50 }
" ], a: Y4 b7 S4 A i9 I% S5 @ Rectangle { color:
"blue"; width:
50; height:
20 }
/ p! c% q+ v/ l; |# ]4 M# k}
Column
QML 中的 Column元素会将其子控件都排列在同一列,相互不重叠。我们还可以使用它的spacing 属性来定义子控件之间的距离。比如下列代码就会产生如图所示的效果:
Column {
5 Q0 C, G1 e0 S! o3 [4 y
spacing:
2
* O( M x& y3 M; z% O1 {4 J' j1 d Rectangle { color:
"red"; width:
50; height:
50 }
, p6 |) u/ V$ k& q7 e Rectangle { color:
"green"; width:
20; height:
50 }
3 n2 U; v% z- T2 l9 d& F+ z$ |2 W n Rectangle { color:
"blue"; width:
50; height:
20 }
6 ^) L8 Q& m+ k5 p: |
}
Grid
QML 中的 Grid元素会将其子控件都均匀地排列在一个网格内,相互不重叠,每一个子控件都被放置在一个网格单元的(0,0)位置,也就是左上角。Grid的rows 和columns属性定义网格的行数和列数,列数默认是4。我们还可以使用Grid的spacing 属性来定义网格单元之间的距离,这里注意水平和垂直方向的spacing都是一样的。比如下列代码就会产生如图所示的效果:
Grid {
( L2 @- a) i7 f% ~ columns:
3
5 M' x- B# D, x( P2 J spacing:
2
) G, W+ @4 S0 Y, L* G2 f. ^" u Rectangle { color:
"red"; width:
50; height:
50 }
, H( W( n4 E# J. b8 L Rectangle { color:
"green"; width:
20; height:
50 }
. I- a. f, }8 p7 N' X5 `: L
Rectangle { color:
"blue"; width:
50; height:
20 }
$ O. I3 P1 ]6 v) N, R
Rectangle { color:
"cyan"; width:
50; height:
50 }
( {1 i% P8 O" y! m
Rectangle { color:
"magenta"; width:
10; height:
10 }
- Z0 g) F! c3 j4 y1 M. S
}
' X, U. y' L4 i( H混合应用
我们还可以将Grid、Row 和 Column 进行混合应用。比如下面的代码会产生如图所示的效果:
Column {
6 k& Y: m8 g: m/ U7 i3 {1 F spacing:
2. I, G8 i4 G( f
Rectangle { color:
"red"; width:
50; height:
50 }
- c. l6 n$ q5 F+ b0 { Row {
/ q4 U3 ~ b/ g7 X S& l spacing:
2
, }( A3 L4 x) l# s i' I' r9 f4 B9 f Rectangle { color:
"yellow"; width:
50; height:
50 }
0 E. G+ u& _8 X( Z+ r
Rectangle { color:
"black"; width:
20; height:
50 }
- j' e. X5 f V0 B5 H& l- u
Rectangle { color:
"blue"; width:
50; height:
20 }
5 w5 u3 \7 f7 Z+ ^3 k
}
' E- k8 R' R l" Y$ z: z4 U
Rectangle { color:
"green"; width:
20; height:
50 }
5 n8 q( O$ j8 t% ~% h
}
, i: l; H7 P2 |: u( R; p
Anchor
以上方法进行排列是不重叠的,而anchor通俗的说是当前图形相对于某一图形的位置(可重叠)
每一个item 都可以被认为具有 7 条隐藏的“anchor lines":left、 horizontalCenter、 right、 top、 verticalCenter、baseline、以及bottom,如下图所示:
····
其中baseline是指的文本所在的线,在上图中并未标出,如果item没有文字的话baselinw就和top的位置是相同的。2 p6 _. N- J; o! A" V) n; E: ^
除此之外,Anchor系统还提供了margins 和offsets。margins 是指一个item和外界之间所留有的空间,而offsets 则可以通过使用 center anchor lines来进行布局。如下图所示
·····
使用 QML anchoring系统,我们可以定义不同items之间的anchor lines之间的关系。例如:
Rectangle { id: rect1; ... }5 Y, y! o- Z5 j8 Q G5 e) ]
Rectangle { id: rect2; anchors.left: rect1.right; anchors.leftMargin: 5; ... }
·····
我们还可以使用多个anchors:
Rectangle { id: rect1; ... }
, H. G! Q8 \) u* m2 hRectangle { id: rect2; anchors.left: rect1.right; anchors.top: rect1.bottom; ... }
·····
通过定义多个水平或垂直的anchors,我们还可以控制item的大小,例如:
Rectangle { id: rect1; x: 0; ... }; x5 G% K5 o6 b @! S) v
Rectangle { id: rect2; anchors.left: rect1.right; anchors.right: rect3.left; ... }
6 Z2 N: u5 B0 t$ t5 g C1 e' nRectangle { id: rect3; x: 150; ... }
·····
注意:出于效率方面的考虑,我们只允许对一个item的邻居和之接父亲使用anchor定义。比如下面的定义是不合法的:
- z; j, ?/ B' |9 S# W2 N. B+ [; f
Item {5 C4 L. _4 `) Q0 u3 t9 U+ {
id: group1; e: { `% |; Q) L1 F6 B
Rectangle { id: rect1; ... }
$ L; C+ A5 {- [( K}& r) P* C2 C$ v
Item {2 N- a; y; T+ J; \& x1 }# l
id: group21 c1 r$ @# s) y
Rectangle { id: rect2; anchors.left: rect1.right; ... } // invalid anchor!! Y; N- S6 ]& Q( U
}
" i X- v8 }) z8 U6 B: F