aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick/doc/src/concepts/positioning/anchors.qdoc
blob: 71af38b5875e458c0119c018fe61792b4a2f5e45 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the documentation of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:FDL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see http://www.qt.io/terms-conditions. For further
** information use the contact form at http://www.qt.io/contact-us.
**
** GNU Free Documentation License Usage
** Alternatively, this file may be used under the terms of the GNU Free
** Documentation License version 1.3 as published by the Free Software
** Foundation and appearing in the file included in the packaging of
** this file. Please review the following information to ensure
** the GNU Free Documentation License version 1.3 requirements
** will be met: http://www.gnu.org/copyleft/fdl.html.
** $QT_END_LICENSE$
**
****************************************************************************/

/*!
\page qtquick-positioning-anchors.html
\title Positioning with Anchors
\brief placing items with anchor properties

\target anchor-layout
In addition to the more traditional \l Grid, \l Row, and \l Column,
Qt Quick also provides a way to layout items using the concept of \e anchors.
Each item can be thought of as having a set of 7 invisible "anchor lines":
\l {Item::anchors.left}{left}, \l {Item::anchors.horizontalCenter}{horizontalCenter},
\l {Item::anchors.right}{right}, \l {Item::anchors.top}{top},
\l {Item::anchors.verticalCenter}{verticalCenter}, \l {Item::anchors.baseline}{baseline},
and \l {Item::anchors.bottom}{bottom}.

\image edges_qml.png

The baseline (not pictured above) corresponds to the imaginary line on which
text would sit. For items with no text it is the same as \e top.

The Qt Quick anchoring system allows you to define relationships between the anchor lines of different items. For example, you can write:

\code
Rectangle { id: rect1; ... }
Rectangle { id: rect2; anchors.left: rect1.right; ... }
\endcode

In this case, the left edge of \e rect2 is bound to the right edge of \e rect1, producing the following:

\image edge1.png


You can specify multiple anchors. For example:

\code
Rectangle { id: rect1; ... }
Rectangle { id: rect2; anchors.left: rect1.right; anchors.top: rect1.bottom; ... }
\endcode

\image edge3.png

By specifying multiple horizontal or vertical anchors you can control the size of an item. Below,
\e rect2 is anchored to the right of \e rect1 and the left of \e rect3. If either of the blue
rectangles are moved, \e rect2 will stretch and shrink as necessary:

\code
Rectangle { id: rect1; x: 0; ... }
Rectangle { id: rect2; anchors.left: rect1.right; anchors.right: rect3.left; ... }
Rectangle { id: rect3; x: 150; ... }
\endcode

\image edge4.png

There are also some convenience anchors. anchors.fill is a convenience that is the same as setting the left,right,top and bottom anchors
to the left,right,top and bottom of the target item. anchors.centerIn is another convenience anchor, and is the same as setting the verticalCenter
and horizontalCenter anchors to the verticalCenter and horizontalCenter of the target item.

\section1 Anchor Margins and Offsets

The anchoring system also allows \e margins and \e offsets to be specified for an item's anchors.
Margins specify the amount of empty space to leave to the outside of an item's anchor, while
offsets allow positioning to be manipulated using the center anchor lines.  An item can
specify its anchor margins individually through \l {Item::anchors.leftMargin}{leftMargin},
\l {Item::anchors.rightMargin}{rightMargin}, \l {Item::anchors.topMargin}{topMargin} and
\l {Item::anchors.bottomMargin}{bottomMargin}, or use \l {Item::}{anchors.margins} to
specify the same margin value for all four edges. Anchor offsets are specified using
\l {Item::anchors.horizontalCenterOffset}{horizontalCenterOffset},
\l {Item::anchors.verticalCenterOffset}{verticalCenterOffset} and
\l {Item::anchors.baselineOffset}{baselineOffset}.

\image margins_qml.png

The following example specifies a left margin:

\code
Rectangle { id: rect1; ... }
Rectangle { id: rect2; anchors.left: rect1.right; anchors.leftMargin: 5; ... }
\endcode

In this case, a margin of 5 pixels is reserved to the left of \e rect2, producing the following:

\image edge2.png

\note Anchor margins only apply to anchors; they are \e not a generic means of applying margins to an \l Item.
If an anchor margin is specified for an edge but the item is not anchored to any item on that
edge, the margin is not applied.

\section1 Changing Anchors

Qt Quick provides the AnchorChanges type for specifying the anchors in a state.

\qml
State {
    name: "anchorRight"
    AnchorChanges {
        target: rect2
        anchors.right: parent.right
        anchors.left: undefined  //remove the left anchor
    }
}
\endqml

AnchorChanges can be animated using the AnchorAnimation type.

\qml
Transition {
    AnchorAnimation {}  //animates any AnchorChanges in the corresponding state change
}
\endqml

Anchors can also be changed imperatively within JavaScript. However, these changes should be
carefully ordered, or they may produce unexpected outcomes. The following example illustrates the issue:

\table
\row
\li
    \code
    //bad code
    Rectangle {
        width: 50
        anchors.left: parent.left

        function reanchorToRight() {
            anchors.right = parent.right
            anchors.left = undefined
        }
    }
    \endcode
\li
    \image anchor_ordering_bad.png
\endtable


When \c reanchorToRight is called, the function first sets the right anchor. At that point, both left
and right anchors are set, and the item will be stretched horizontally to fill its parent. When the left
anchor is unset, the new width will remain. Thus when updating anchors within JavaScript,  you should
first unset any anchors that are no longer required, and only then set any new anchors that are required,
as shown below:

\table
\row
\li
    \qml
    Rectangle {
        width: 50
        anchors.left: parent.left

        function reanchorToRight() {
            anchors.left = undefined
            anchors.right = parent.right
        }
    }
    \endqml
\li
    \image anchor_ordering.png
\endtable

Because the evaluation order of bindings is not defined, it is not recommended to change anchors via
conditional bindings, as this can lead to the ordering issue described above. In the following example
the Rectangle will eventually grow to the full width of its parent, because both left and right anchors
will be simultaneously set during binding update.

\code
//bad code
Rectangle {
    width: 50; height: 50
    anchors.left: state == "right" ? undefined : parent.left;
    anchors.right: state == "right" ? parent.right : undefined;
}
\endcode

This should be rewritten to use AnchorChanges instead, as AnchorChanges will automatically handle
ordering issues internally.

\section1 Restrictions

For performance reasons, you can only anchor an item to its siblings and direct parent. For example,
the following anchor is invalid and would produce a warning:

\code
//bad code
Item {
    id: group1
    Rectangle { id: rect1; ... }
}
Item {
    id: group2
    Rectangle { id: rect2; anchors.left: rect1.right; ... }    // invalid anchor!
}
\endcode

Also, anchor-based layouts cannot be mixed with absolute positioning. If an item specifies its
\l {Item::}{x} position and also sets \l {Item::}{anchors.left},
or anchors its left and right edges but additionally sets a \l {Item::}{width}, the
result is undefined, as it would not be clear whether the item should use anchoring or absolute
positioning. The same can be said for setting an item's \l {Item::}{y} and \l {Item::}{height}
with \l {Item::}{anchors.top} and \l {Item::}{anchors.bottom}, or setting \l {Item::}{anchors.fill}
as well as \l {Item::}{width} or \l {Item::}{height}. The same applies when using positioners
such as Row and Grid, which may set the item's \l {Item::}{x} and \l {Item::}{y} properties.
If you wish to change from using
anchor-based to absolute positioning, you can clear an anchor value by setting it to \c undefined.

*/