概述
使用Qt做过UI的一定对QHBoxLayout, QVBoxLayout, 和QGridLayout这三个最重要也最常使用的layout managers非常熟悉。那么在QML中又是如何控制和管理UI布局的呢?那么我们这篇文章就为大家介绍这些基础知识。
首先,QML同样允许大家使用硬编码的方式将位置数值直接写到代码中,但是这样做首先难以适应UI的调整,其次代码维护起来也很困难。因此我们不推荐这样做。推荐大家使用的是以下三种布局管理器:Row,、Column、Grid,以及使用Anchor进行布局。
Row
QML 中的 Row 元素会将其子控件都排列在同一行,相互不重叠。我们还可以使用它的spacing 属性来定义子控件之间的距离。比如下列代码就会产生如图所示的效果:
Row {
; r8 ]# _7 |* N3 y+ L- K% p
spacing:
2) R* ?7 r( p+ k/ c Z
Rectangle { color:
"red"; width:
50; height:
50 }
6 ~1 O, v9 }9 N) r. I+ D! W, o Rectangle { color:
"green"; width:
20; height:
50 }
( q6 e/ R' | d- P, x
Rectangle { color:
"blue"; width:
50; height:
20 }
6 M: F" |' M7 i& f/ C2 n}
Column
QML 中的 Column元素会将其子控件都排列在同一列,相互不重叠。我们还可以使用它的spacing 属性来定义子控件之间的距离。比如下列代码就会产生如图所示的效果:
Column {
+ F0 O( a a- b spacing:
2
@6 H9 O- U% \1 U0 E Rectangle { color:
"red"; width:
50; height:
50 }
2 W( M) F$ }( c: y$ J+ c# e! M6 ?
Rectangle { color:
"green"; width:
20; height:
50 }
. }2 V3 V- P" Y
Rectangle { color:
"blue"; width:
50; height:
20 }
' y4 m+ e5 F8 l}
Grid
QML 中的 Grid元素会将其子控件都均匀地排列在一个网格内,相互不重叠,每一个子控件都被放置在一个网格单元的(0,0)位置,也就是左上角。Grid的rows 和columns属性定义网格的行数和列数,列数默认是4。我们还可以使用Grid的spacing 属性来定义网格单元之间的距离,这里注意水平和垂直方向的spacing都是一样的。比如下列代码就会产生如图所示的效果:
Grid {
0 N6 y) h9 o3 _# h8 `. Y
columns:
3* X9 N8 C, _1 B5 E% b0 e# Y" o' ]( A
spacing:
2
# }& X; f& p' k# o! q Rectangle { color:
"red"; width:
50; height:
50 }
3 P# `' b2 \9 V8 h6 N
Rectangle { color:
"green"; width:
20; height:
50 }
# O5 V" l5 x! R# J7 f% z, r Rectangle { color:
"blue"; width:
50; height:
20 }
h; X" [( G; q3 ^' |5 X R Rectangle { color:
"cyan"; width:
50; height:
50 }
6 ^% H/ o$ P5 ?' Q6 m- v+ J Rectangle { color:
"magenta"; width:
10; height:
10 }
: g: v6 L, C$ B, S: F0 V0 W) f5 R9 f
}
& r( k4 k5 r1 i/ ^2 Z( ?7 T
混合应用
我们还可以将Grid、Row 和 Column 进行混合应用。比如下面的代码会产生如图所示的效果:
Column {
+ {4 n# b: w! I6 ?9 @7 Y. Y spacing:
2
* k0 i. ]5 w& _$ m Rectangle { color:
"red"; width:
50; height:
50 }
- q7 a! A" d: i" M4 u5 `/ d4 [% K/ [
Row {
8 B1 e [) C% Y2 q spacing:
2
) r, S& s+ v5 G Rectangle { color:
"yellow"; width:
50; height:
50 }
/ ^: ?) W& ?0 C
Rectangle { color:
"black"; width:
20; height:
50 }
m2 _' }" P7 v% b1 L! S
Rectangle { color:
"blue"; width:
50; height:
20 }
; d& o, P3 c$ |# v2 ~5 l3 }! E
}
0 T. ^6 B Q& y J ~6 I( ] Rectangle { color:
"green"; width:
20; height:
50 }
( q5 t% y. k1 f! O" h6 {}
t8 y% j* v8 Z* Y# i/ h8 u' T9 ?Anchor
以上方法进行排列是不重叠的,而anchor通俗的说是当前图形相对于某一图形的位置(可重叠)
每一个item 都可以被认为具有 7 条隐藏的“anchor lines":left、 horizontalCenter、 right、 top、 verticalCenter、baseline、以及bottom,如下图所示:
····
其中baseline是指的文本所在的线,在上图中并未标出,如果item没有文字的话baselinw就和top的位置是相同的。: B6 S) c7 C, V5 A. X4 R( M
除此之外,Anchor系统还提供了margins 和offsets。margins 是指一个item和外界之间所留有的空间,而offsets 则可以通过使用 center anchor lines来进行布局。如下图所示
·····
使用 QML anchoring系统,我们可以定义不同items之间的anchor lines之间的关系。例如:
Rectangle { id: rect1; ... }5 @8 `* G. W! u6 m x+ a% p3 R
Rectangle { id: rect2; anchors.left: rect1.right; anchors.leftMargin: 5; ... }
·····
我们还可以使用多个anchors:
Rectangle { id: rect1; ... }: G' }' `+ L% O
Rectangle { id: rect2; anchors.left: rect1.right; anchors.top: rect1.bottom; ... }
·····
通过定义多个水平或垂直的anchors,我们还可以控制item的大小,例如:
Rectangle { id: rect1; x: 0; ... }* }$ I. k& Q) }1 F
Rectangle { id: rect2; anchors.left: rect1.right; anchors.right: rect3.left; ... }6 a5 W+ X( C/ t7 A: U \' @& y) I
Rectangle { id: rect3; x: 150; ... }
·····
注意:出于效率方面的考虑,我们只允许对一个item的邻居和之接父亲使用anchor定义。比如下面的定义是不合法的:
0 j- P# v/ D9 h! R6 s
Item {! H* w( P4 ~; K2 ]- ^$ Y
id: group1- @7 X: w5 X1 v" }
Rectangle { id: rect1; ... }5 d: x" ^$ p# L0 R
}; e7 \$ d4 R% x/ o9 [- I' L: X0 Z
Item {$ z6 h% t1 B' r/ \7 G6 H
id: group2
5 d% \; j- a1 ]+ d Rectangle { id: rect2; anchors.left: rect1.right; ... } // invalid anchor!4 V+ z+ m1 S/ d; I; Q$ ]
}6 F" Q; |3 G: {% P: o9 r