概述
使用Qt做过UI的一定对QHBoxLayout, QVBoxLayout, 和QGridLayout这三个最重要也最常使用的layout managers非常熟悉。那么在QML中又是如何控制和管理UI布局的呢?那么我们这篇文章就为大家介绍这些基础知识。
首先,QML同样允许大家使用硬编码的方式将位置数值直接写到代码中,但是这样做首先难以适应UI的调整,其次代码维护起来也很困难。因此我们不推荐这样做。推荐大家使用的是以下三种布局管理器:Row,、Column、Grid,以及使用Anchor进行布局。
Row
QML 中的 Row 元素会将其子控件都排列在同一行,相互不重叠。我们还可以使用它的spacing 属性来定义子控件之间的距离。比如下列代码就会产生如图所示的效果:
Row {
1 A3 n& y( C" V# x" ]9 y- G# X
spacing:
2
0 Z# G0 B% ?2 k; H" p Rectangle { color:
"red"; width:
50; height:
50 }
K6 W) P0 z; F9 \* k* w$ O
Rectangle { color:
"green"; width:
20; height:
50 }
/ C5 w( k) ~' W: {8 h( T Rectangle { color:
"blue"; width:
50; height:
20 }
( `; M" J2 f" ?' e- s* K
}
Column
QML 中的 Column元素会将其子控件都排列在同一列,相互不重叠。我们还可以使用它的spacing 属性来定义子控件之间的距离。比如下列代码就会产生如图所示的效果:
Column {
! V8 A* Z, F/ _ W
spacing:
2
5 O1 s$ X4 V# I' l2 O Rectangle { color:
"red"; width:
50; height:
50 }
& Y5 i+ S. E1 g8 c
Rectangle { color:
"green"; width:
20; height:
50 }
* t8 w0 c9 W7 S. a# K% A
Rectangle { color:
"blue"; width:
50; height:
20 }
$ R& C/ k: v6 B3 b
}
Grid
QML 中的 Grid元素会将其子控件都均匀地排列在一个网格内,相互不重叠,每一个子控件都被放置在一个网格单元的(0,0)位置,也就是左上角。Grid的rows 和columns属性定义网格的行数和列数,列数默认是4。我们还可以使用Grid的spacing 属性来定义网格单元之间的距离,这里注意水平和垂直方向的spacing都是一样的。比如下列代码就会产生如图所示的效果:
Grid {
# c) w- Q4 p3 s5 {
columns:
3- c, k& X) X" n/ @) l5 {
spacing:
21 `8 O+ k; P8 L5 p
Rectangle { color:
"red"; width:
50; height:
50 }
/ y$ T, N( w6 a E, d* `+ v. b
Rectangle { color:
"green"; width:
20; height:
50 }
1 B3 e. {& q2 T8 q* ~ Rectangle { color:
"blue"; width:
50; height:
20 }
8 g. a& P q3 S; Y0 h0 O+ y Rectangle { color:
"cyan"; width:
50; height:
50 }
' `+ t; T. ?2 ?
Rectangle { color:
"magenta"; width:
10; height:
10 }
# M, R+ L& v- G3 d- F9 ~6 ^
}
+ @0 }0 O/ r& x Y: W5 _
混合应用
我们还可以将Grid、Row 和 Column 进行混合应用。比如下面的代码会产生如图所示的效果:
Column {
) d# Z' O8 |! o" v+ _. \ spacing:
2: V, `9 O1 A9 e) ?, g( h
Rectangle { color:
"red"; width:
50; height:
50 }
: l5 _; a7 ^8 m6 w
Row {
6 e3 g' {2 r' s& K9 e
spacing:
2
+ Y5 ^, c# O. r. |) f Rectangle { color:
"yellow"; width:
50; height:
50 }
& E5 ~% C$ t* q
Rectangle { color:
"black"; width:
20; height:
50 }
, L* ]& V" j! a1 b1 p4 v Rectangle { color:
"blue"; width:
50; height:
20 }
# F; k7 X* j6 `: F$ \ }
3 G3 T8 N/ w8 z$ k1 L Rectangle { color:
"green"; width:
20; height:
50 }
. c4 [4 Y4 R# s, w& Z* \ }}
$ v2 w! }' v8 E9 j
Anchor
以上方法进行排列是不重叠的,而anchor通俗的说是当前图形相对于某一图形的位置(可重叠)
每一个item 都可以被认为具有 7 条隐藏的“anchor lines":left、 horizontalCenter、 right、 top、 verticalCenter、baseline、以及bottom,如下图所示:
····
其中baseline是指的文本所在的线,在上图中并未标出,如果item没有文字的话baselinw就和top的位置是相同的。
1 ^/ ?- D, a4 I# h# u7 |除此之外,Anchor系统还提供了margins 和offsets。margins 是指一个item和外界之间所留有的空间,而offsets 则可以通过使用 center anchor lines来进行布局。如下图所示
·····
使用 QML anchoring系统,我们可以定义不同items之间的anchor lines之间的关系。例如:
Rectangle { id: rect1; ... }; R2 W, N7 w4 s% ]
Rectangle { id: rect2; anchors.left: rect1.right; anchors.leftMargin: 5; ... }
·····
我们还可以使用多个anchors:
Rectangle { id: rect1; ... }7 q" p" {. B9 m
Rectangle { id: rect2; anchors.left: rect1.right; anchors.top: rect1.bottom; ... }
·····
通过定义多个水平或垂直的anchors,我们还可以控制item的大小,例如:
Rectangle { id: rect1; x: 0; ... }
' A [3 e" N M8 WRectangle { id: rect2; anchors.left: rect1.right; anchors.right: rect3.left; ... }" Q! `2 X4 A* q8 `& L
Rectangle { id: rect3; x: 150; ... }
·····
注意:出于效率方面的考虑,我们只允许对一个item的邻居和之接父亲使用anchor定义。比如下面的定义是不合法的:
! ~6 Y$ R" Y$ t9 U+ aItem {$ |% d J# S1 x. T
id: group1
6 U: P6 H2 b4 ]6 w+ }# K5 \6 p Rectangle { id: rect1; ... } d n3 x# H0 P0 l1 c @9 V
}" T0 T5 |' ~9 [% r
Item {+ v& w, }1 w: e- A6 m: S, D
id: group2
I5 x! b# k: W9 k Rectangle { id: rect2; anchors.left: rect1.right; ... } // invalid anchor!: t, ^. `7 y5 U5 k: b4 u+ ~3 Z, _
}7 c6 v3 S2 G9 t/ _