1// Copyright (C) 2017 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
5\page qtquick-positioning-anchors.html
6\title Positioning with Anchors
7\brief placing items with anchor properties
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}.
20The baseline (not pictured above) corresponds to the imaginary line on which
21text would sit. For items with no text it is the same as \e top.
23The Qt Quick anchoring system allows you to define relationships between the anchor lines of different items. For example, you can write:
26Rectangle { id: rect1; ... }
27Rectangle { id: rect2; anchors.left: rect1.right; ... }
30In this case, the left edge of \e rect2 is bound to the right edge of \e rect1, producing the following:
35You can specify multiple anchors. For example:
38Rectangle { id: rect1; ... }
39Rectangle { id: rect2; anchors.left: rect1.right; anchors.top: rect1.bottom; ... }
44By specifying multiple horizontal or vertical anchors you can control the size of an item. Below,
45\e rect2 is anchored to the right of \e rect1 and the left of \e rect3. If either of the blue
46rectangles are moved, \e rect2 will stretch and shrink as necessary:
49Rectangle { id: rect1; x: 0; ... }
50Rectangle { id: rect2; anchors.left: rect1.right; anchors.right: rect3.left; ... }
51Rectangle { id: rect3; x: 150; ... }
56There are also some convenience anchors. anchors.fill is a convenience that is the same as setting the left,right,top and bottom anchors
57to the left,right,top and bottom of the target item. anchors.centerIn is another convenience anchor, and is the same as setting the verticalCenter
58and horizontalCenter anchors to the verticalCenter and horizontalCenter of the target item.
60\section1 Anchor Margins and Offsets
62The anchoring system also allows \e margins and \e offsets to be specified for an item's anchors.
63Margins specify the amount of empty space to leave to the outside of an item's anchor, while
64offsets allow positioning to be manipulated using the center anchor lines. An item can
65specify its anchor margins individually through \l {Item::anchors.leftMargin}{leftMargin},
66\l {Item::anchors.rightMargin}{rightMargin}, \l {Item::anchors.topMargin}{topMargin} and
67\l {Item::anchors.bottomMargin}{bottomMargin}, or use \l {Item::}{anchors.margins} to
68specify the same margin value for all four edges. Anchor offsets are specified using
69\l {Item::anchors.horizontalCenterOffset}{horizontalCenterOffset},
70\l {Item::anchors.verticalCenterOffset}{verticalCenterOffset} and
71\l {Item::anchors.baselineOffset}{baselineOffset}.
75The following example specifies a left margin:
78Rectangle { id: rect1; ... }
79Rectangle { id: rect2; anchors.left: rect1.right; anchors.leftMargin: 5; ... }
82In this case, a margin of 5 pixels is reserved to the left of \e rect2, producing the following:
86\note Anchor margins only apply to anchors; they are \e not a generic means of applying margins to an \l Item.
87If an anchor margin is specified for an edge but the item is not anchored to any item on that
88edge, the margin is not applied.
90\section1 Changing Anchors
92Qt Quick provides the AnchorChanges type for specifying the anchors in a state.
99 anchors.right: parent.right
100 anchors.left: undefined //remove the left anchor
105AnchorChanges can be animated using the AnchorAnimation type.
109 AnchorAnimation {} //animates any AnchorChanges in the corresponding state change
113Anchors can also be changed imperatively within JavaScript. However, these changes should be
114carefully ordered, or they may produce unexpected outcomes. The following example illustrates the issue:
123 anchors.left: parent.left
125 function reanchorToRight() {
126 anchors.right = parent.right
127 anchors.left = undefined
132 \image anchor_ordering_bad.png
136When \c reanchorToRight is called, the function first sets the right anchor. At that point, both left
137and right anchors are set, and the item will be stretched horizontally to fill its parent. When the left
138anchor is unset, the new width will remain. Thus when updating anchors within JavaScript, you should
139first unset any anchors that are no longer required, and only then set any new anchors that are required,
148 anchors.left: parent.left
150 function reanchorToRight() {
151 anchors.left = undefined
152 anchors.right = parent.right
157 \image anchor_ordering.png
160Because the evaluation order of bindings is not defined, it is not recommended to change anchors via
161conditional bindings, as this can lead to the ordering issue described above. In the following example
162the Rectangle will eventually grow to the full width of its parent, because both left and right anchors
163will be simultaneously set during binding update.
168 width: 50; height: 50
169 anchors.left: state == "right" ? undefined : parent.left;
170 anchors.right: state == "right" ? parent.right : undefined;
174This should be rewritten to use AnchorChanges instead, as AnchorChanges will automatically handle
175ordering issues internally.
177\section1 Restrictions
179For performance reasons, you can only anchor an item to its siblings and direct parent. For example,
180the following anchor is invalid and would produce a warning:
186 Rectangle { id: rect1; ... }
190 Rectangle { id: rect2; anchors.left: rect1.right; ... } // invalid anchor!
194Also, anchor-based layouts cannot be mixed with absolute positioning. If an item specifies its
195\l {Item::}{x} position and also sets \l {Item::}{anchors.left},
196or anchors its left and right edges but additionally sets a \l {Item::}{width}, the
197result is undefined, as it would not be clear whether the item should use anchoring or absolute
198positioning. The same can be said for setting an item's \l {Item::}{y} and \l {Item::}{height}
199with \l {Item::}{anchors.top} and \l {Item::}{anchors.bottom}, or setting \l {Item::}{anchors.fill}
200as well as \l {Item::}{width} or \l {Item::}{height}. The same applies when using positioners
201such as Row and Grid, which may set the item's \l {Item::}{x} and \l {Item::}{y} properties.
202If you wish to change from using
203anchor-based to absolute positioning, you can clear an anchor value by setting it to \c undefined.