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
10In addition to the more traditional \l Grid, \l Row, and \l Column,
11Qt Quick also provides a way to layout items using the concept of \e anchors.
12Each 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},
16and \l {Item::anchors.bottom}{bottom}.
17
18\image edges_qml.png
19 {Rectangle showing six anchor lines: left, right, top, bottom, and centers}
20
21The baseline (not pictured above) corresponds to the imaginary line on which
22text would sit. For items with no text it is the same as \e top.
23
24The Qt Quick anchoring system allows you to define relationships between the anchor lines of different items. For example, you can write:
25
26\code
27Rectangle { id: rect1; ... }
28Rectangle { id: rect2; anchors.left: rect1.right; ... }
29\endcode
30
31In 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
36You can specify multiple anchors. For example:
37
38\code
39Rectangle { id: rect1; ... }
40Rectangle { 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
45By 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
47rectangles are moved, \e rect2 will stretch and shrink as necessary:
48
49\code
50Rectangle { id: rect1; x: 0; ... }
51Rectangle { id: rect2; anchors.left: rect1.right; anchors.right: rect3.left; ... }
52Rectangle { id: rect3; x: 150; ... }
53\endcode
54
55\image edge4.png {rect2 stretched between rect1 on left and rect3 on right}
56
57There are also some convenience anchors. \c anchors.fill is a convenience that
58is the same as setting the left, right, top, and bottom anchors to the
59left, right, top and bottom of the target item. \c anchors.centerIn is another
60convenience anchor, and is the same as setting the \c verticalCenter and
61\c horizontalCenter anchors to the \c verticalCenter and \c horizontalCenter of
62the target item.
63
64\section1 Anchor Margins and Offsets
65
66The anchoring system also allows \e margins and \e offsets to be specified for an item's anchors.
67Margins specify the amount of empty space to leave to the outside of an item's anchor, while
68offsets allow positioning to be manipulated using the center anchor lines. An item can
69specify 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
72specify 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
80The following example specifies a left margin:
81
82\code
83Rectangle { id: rect1; ... }
84Rectangle { id: rect2; anchors.left: rect1.right; anchors.leftMargin: 5; ... }
85\endcode
86
87In 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.
92If an anchor margin is specified for an edge but the item is not anchored to any item on that
93edge, the margin is not applied.
94
95\section1 Changing Anchors
96
97Qt Quick provides the AnchorChanges type for specifying the anchors in a state.
98
99\qml
100State {
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
110AnchorChanges can be animated using the AnchorAnimation type.
111
112\qml
113Transition {
114 AnchorAnimation {} //animates any AnchorChanges in the corresponding state change
115}
116\endqml
117
118Anchors can also be changed imperatively within JavaScript. However, these changes should be
119carefully 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
142When \c reanchorToRight is called, the function first sets the right anchor. At that point, both left
143and right anchors are set, and the item will be stretched horizontally to fill its parent. When the left
144anchor is unset, the new width will remain. Thus when updating anchors within JavaScript, you should
145first unset any anchors that are no longer required, and only then set any new anchors that are required,
146as 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
168Because the evaluation order of bindings is not defined, it is not recommended to change anchors via
169conditional bindings, as this can lead to the ordering issue described above. In the following example
170the \c Rectangle will eventually grow to the full width of its parent, because both left and right anchors
171will be simultaneously set during binding update.
172
173\code
174// May produce unexpected results
175Rectangle {
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
182This should be rewritten to use \l AnchorChanges instead, as \l AnchorChanges
183will automatically handle ordering issues internally. Here's how to rewrite the
184above example correctly:
185
186\qml
187// Correct code
188Rectangle {
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
209For performance reasons, you can only anchor an item to its siblings and direct parent. For example,
210the following anchor is invalid and would produce a warning:
211
212\code
213//bad code
214Item {
215 id: group1
216 Rectangle { id: rect1; ... }
217}
218Item {
219 id: group2
220 Rectangle { id: rect2; anchors.left: rect1.right; ... } // invalid anchor!
221}
222\endcode
223
224Also, 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},
226or anchors its left and right edges but additionally sets a \l {Item::}{width}, the
227result is undefined, as it would not be clear whether the item should use anchoring or absolute
228positioning. The same can be said for setting an item's \l {Item::}{y} and \l {Item::}{height}
229with \l {Item::}{anchors.top} and \l {Item::}{anchors.bottom}, or setting \l {Item::}{anchors.fill}
230as well as \l {Item::}{width} or \l {Item::}{height}. The same applies when using positioners
231such as Row and Grid, which may set the item's \l {Item::}{x} and \l {Item::}{y} properties.
232If you wish to change from using
233anchor-based to absolute positioning, you can clear an anchor value by setting it to \c undefined.
234
235*/