Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
anchors.qdoc
Go to the documentation of this file.
1
// Copyright (C) 2017 The Qt Company Ltd.
2
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
3
4
/*!
5
\page qtquick-positioning-anchors.html
6
\title Positioning with Anchors
7
\brief placing items with anchor properties
8
9
\keyword anchor-layout
10
In addition to the more traditional \l Grid, \l Row, and \l Column,
11
Qt Quick also provides a way to layout items using the concept of \e anchors.
12
Each item can be thought of as having a set of 7 invisible "anchor lines":
13
\l {Item::anchors.left}{left}, \l {Item::anchors.horizontalCenter}{horizontalCenter},
14
\l {Item::anchors.right}{right}, \l {Item::anchors.top}{top},
15
\l {Item::anchors.verticalCenter}{verticalCenter}, \l {Item::anchors.baseline}{baseline},
16
and \l {Item::anchors.bottom}{bottom}.
17
18
\image edges_qml.png
19
{Rectangle showing six anchor lines: left, right, top, bottom, and centers}
20
21
The baseline (not pictured above) corresponds to the imaginary line on which
22
text would sit. For items with no text it is the same as \e top.
23
24
The Qt Quick anchoring system allows you to define relationships between the anchor lines of different items. For example, you can write:
25
26
\code
27
Rectangle { id: rect1; ... }
28
Rectangle { id: rect2; anchors.left: rect1.right; ... }
29
\endcode
30
31
In this case, the left edge of \e rect2 is bound to the right edge of \e rect1, producing the following:
32
33
\image edge1.png {rect1 and rect2 side by side with left edge anchored to right}
34
35
36
You can specify multiple anchors. For example:
37
38
\code
39
Rectangle { id: rect1; ... }
40
Rectangle { id: rect2; anchors.left: rect1.right; anchors.top: rect1.bottom; ... }
41
\endcode
42
43
\image edge3.png {rect2 positioned below and to the right of rect1}
44
45
By specifying multiple horizontal or vertical anchors you can control the size of an item. Below,
46
\e rect2 is anchored to the right of \e rect1 and the left of \e rect3. If either of the blue
47
rectangles are moved, \e rect2 will stretch and shrink as necessary:
48
49
\code
50
Rectangle { id: rect1; x: 0; ... }
51
Rectangle { id: rect2; anchors.left: rect1.right; anchors.right: rect3.left; ... }
52
Rectangle { id: rect3; x: 150; ... }
53
\endcode
54
55
\image edge4.png {rect2 stretched between rect1 on left and rect3 on right}
56
57
There are also some convenience anchors. \c anchors.fill is a convenience that
58
is the same as setting the left, right, top, and bottom anchors to the
59
left, right, top and bottom of the target item. \c anchors.centerIn is another
60
convenience anchor, and is the same as setting the \c verticalCenter and
61
\c horizontalCenter anchors to the \c verticalCenter and \c horizontalCenter of
62
the target item.
63
64
\section1 Anchor Margins and Offsets
65
66
The anchoring system also allows \e margins and \e offsets to be specified for an item's anchors.
67
Margins specify the amount of empty space to leave to the outside of an item's anchor, while
68
offsets allow positioning to be manipulated using the center anchor lines. An item can
69
specify its anchor margins individually through \l {Item::anchors.leftMargin}{leftMargin},
70
\l {Item::anchors.rightMargin}{rightMargin}, \l {Item::anchors.topMargin}{topMargin} and
71
\l {Item::anchors.bottomMargin}{bottomMargin}, or use \l {Item::}{anchors.margins} to
72
specify the same margin value for all four edges. Anchor offsets are specified using
73
\l {Item::anchors.horizontalCenterOffset}{horizontalCenterOffset},
74
\l {Item::anchors.verticalCenterOffset}{verticalCenterOffset} and
75
\l {Item::anchors.baselineOffset}{baselineOffset}.
76
77
\image margins_qml.png
78
{Rectangle with labeled margin areas: top, bottom, left, right}
79
80
The following example specifies a left margin:
81
82
\code
83
Rectangle { id: rect1; ... }
84
Rectangle { id: rect2; anchors.left: rect1.right; anchors.leftMargin: 5; ... }
85
\endcode
86
87
In this case, a margin of 5 pixels is reserved to the left of \e rect2, producing the following:
88
89
\image edge2.png {rect1 and rect2 side by side with margin gap between them}
90
91
\note Anchor margins only apply to anchors; they are \e not a generic means of applying margins to an \l Item.
92
If an anchor margin is specified for an edge but the item is not anchored to any item on that
93
edge, the margin is not applied.
94
95
\section1 Changing Anchors
96
97
Qt Quick provides the AnchorChanges type for specifying the anchors in a state.
98
99
\qml
100
State {
101
name: "anchorRight"
102
AnchorChanges {
103
target: rect2
104
anchors.right: parent.right
105
anchors.left: undefined //remove the left anchor
106
}
107
}
108
\endqml
109
110
AnchorChanges can be animated using the AnchorAnimation type.
111
112
\qml
113
Transition {
114
AnchorAnimation {} //animates any AnchorChanges in the corresponding state change
115
}
116
\endqml
117
118
Anchors can also be changed imperatively within JavaScript. However, these changes should be
119
carefully ordered, or they may produce unexpected outcomes. The following example illustrates the issue:
120
121
\table
122
\row
123
\li
124
\code
125
// May produce unexpected results
126
Rectangle {
127
width: 50
128
anchors.left: parent.left
129
130
function reanchorToRight() {
131
anchors.right = parent.right
132
anchors.left = undefined
133
}
134
}
135
\endcode
136
\li
137
\image anchor_ordering_bad.png
138
{Three steps showing rect1 stretching unexpectedly when reanchoring}
139
\endtable
140
141
142
When \c reanchorToRight is called, the function first sets the right anchor. At that point, both left
143
and right anchors are set, and the item will be stretched horizontally to fill its parent. When the left
144
anchor is unset, the new width will remain. Thus when updating anchors within JavaScript, you should
145
first unset any anchors that are no longer required, and only then set any new anchors that are required,
146
as shown below:
147
148
\table
149
\row
150
\li
151
\qml
152
// Correct code
153
Rectangle {
154
width: 50
155
anchors.left: parent.left
156
157
function reanchorToRight() {
158
anchors.left = undefined
159
anchors.right = parent.right
160
}
161
}
162
\endqml
163
\li
164
\image anchor_ordering.png
165
{Three steps showing rect1 correctly moving from left to right anchor}
166
\endtable
167
168
Because the evaluation order of bindings is not defined, it is not recommended to change anchors via
169
conditional bindings, as this can lead to the ordering issue described above. In the following example
170
the \c Rectangle will eventually grow to the full width of its parent, because both left and right anchors
171
will be simultaneously set during binding update.
172
173
\code
174
// May produce unexpected results
175
Rectangle {
176
width: 50; height: 50
177
anchors.left: state == "right" ? undefined : parent.left;
178
anchors.right: state == "right" ? parent.right : undefined;
179
}
180
\endcode
181
182
This should be rewritten to use \l AnchorChanges instead, as \l AnchorChanges
183
will automatically handle ordering issues internally. Here's how to rewrite the
184
above example correctly:
185
186
\qml
187
// Correct code
188
Rectangle {
189
id: rect
190
width: 50; height: 50
191
anchors.left: parent.left // initial position
192
193
states: State {
194
name: "rightAligned"
195
AnchorChanges {
196
target: rect
197
anchors.left: undefined
198
anchors.right: parent.right
199
}
200
}
201
function toggleAnchoring() {
202
parent.state = (parent.state == "" ? "rightAligned" : "")
203
}
204
}
205
\endqml
206
207
\section1 Restrictions
208
209
For performance reasons, you can only anchor an item to its siblings and direct parent. For example,
210
the following anchor is invalid and would produce a warning:
211
212
\code
213
//bad code
214
Item {
215
id: group1
216
Rectangle { id: rect1; ... }
217
}
218
Item {
219
id: group2
220
Rectangle { id: rect2; anchors.left: rect1.right; ... } // invalid anchor!
221
}
222
\endcode
223
224
Also, anchor-based layouts cannot be mixed with absolute positioning. If an item specifies its
225
\l {Item::}{x} position and also sets \l {Item::}{anchors.left},
226
or anchors its left and right edges but additionally sets a \l {Item::}{width}, the
227
result is undefined, as it would not be clear whether the item should use anchoring or absolute
228
positioning. The same can be said for setting an item's \l {Item::}{y} and \l {Item::}{height}
229
with \l {Item::}{anchors.top} and \l {Item::}{anchors.bottom}, or setting \l {Item::}{anchors.fill}
230
as well as \l {Item::}{width} or \l {Item::}{height}. The same applies when using positioners
231
such as Row and Grid, which may set the item's \l {Item::}{x} and \l {Item::}{y} properties.
232
If you wish to change from using
233
anchor-based to absolute positioning, you can clear an anchor value by setting it to \c undefined.
234
235
*/
qtdeclarative
src
quick
doc
src
concepts
positioning
anchors.qdoc
Generated on
for Qt by
1.16.1