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
propertybinding.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 qtqml-syntax-propertybinding.html
6
\title Property Binding
7
\brief binding object properties
8
9
An object's property can be assigned a static value which stays constant until it
10
is explicitly assigned a new value. However, to make the fullest use of QML and its
11
built-in support for dynamic object behaviors, most QML objects use \e {property bindings}.
12
13
Property bindings are a core feature of QML that lets developers specify relationships
14
between different object properties. When a property's \e dependencies change in
15
value, the property is automatically updated according to the specified relationship.
16
17
Behind the scenes, the QML engine monitors the property's dependencies (that is,
18
the variables in the binding expression). When a change is detected, the QML engine
19
re-evaluates the binding expression and applies the new result to the property.
20
21
\section1 Overview
22
23
To create a property binding, a property is assigned a JavaScript expression that
24
evaluates to the desired value. At its simplest, a binding may be a reference to
25
another property. Take the following example, where the blue \l Rectangle's height
26
is bound to the height of its parent:
27
28
\qml
29
Rectangle {
30
width: 200; height: 200
31
32
Rectangle {
33
width: 100
34
height: parent.height
35
color: "blue"
36
}
37
}
38
\endqml
39
40
Whenever the height of the parent rectangle changes, the height of the blue
41
rectangle automatically updates to be of the same value.
42
43
A binding can contain any valid JavaScript expression or statement, as QML uses
44
a standards compliant JavaScript engine. Bindings can access object properties,
45
call methods and use built-in JavaScript objects such as \c Date and \c Math.
46
Below are other possible bindings for the previous example:
47
48
\code
49
height: parent.height / 2
50
51
height: Math.min(parent.width, parent.height)
52
53
height: parent.height > 100 ? parent.height : parent.height/2
54
55
height: {
56
if (parent.height > 100)
57
return parent.height
58
else
59
return parent.height / 2
60
}
61
62
height: someMethodThatReturnsHeight()
63
\endcode
64
65
Below is a more complex example involving more objects and types:
66
67
\qml
68
Column {
69
id: column
70
width: 200
71
height: 200
72
73
Rectangle {
74
id: topRect
75
width: Math.max(bottomRect.width, parent.width/2)
76
height: (parent.height / 3) + 10
77
color: "yellow"
78
79
TextInput {
80
id: myTextInput
81
text: "Hello QML!"
82
}
83
}
84
85
Rectangle {
86
id: bottomRect
87
width: 100
88
height: 50
89
color: myTextInput.text.length <= 10 ? "red" : "blue"
90
}
91
}
92
\endqml
93
94
In the previous example,
95
\list
96
\li \c topRect.width depends on \c bottomRect.width and \c column.width
97
\li \c topRect.height depends on \c column.height
98
\li \c bottomRect.color depends on \c myTextInput.text.length
99
\endlist
100
101
In addition, any properties referenced within a JavaScript function that is
102
itself used as a binding will be re-evaluated. For example, in the snippet
103
below, whenever the \c enabled property of the \c Rectangle changes, the
104
bindings for the \c x and \c y properties will be re-evaluated:
105
106
\snippet qml/function-call-binding.qml rectangle
107
108
Syntactically, bindings are allowed to be of arbitrary complexity. However, if
109
a binding is overly complex - such as involving multiple lines, or imperative
110
loops - it could indicate that the binding is being used for more than describing
111
property relationships. Complex bindings can reduce code performance, readability,
112
and maintainability. It may be a good idea to redesign components that have
113
complex bindings, or at least factor the binding out into a separate function.
114
As a general rule, users should not rely on the evaluation order of bindings.
115
116
\sa {Positioning with Anchors}
117
118
119
\target qml-javascript-assignment
120
\section1 Creating Property Bindings from JavaScript
121
122
A property with a binding is automatically updated as necessary. However, if the
123
property is later assigned a static value from a JavaScript statement, the binding
124
will be removed.
125
126
For example, the \l Rectangle below initially ensures that its \c height is always
127
twice its \c width. However, when the space key is pressed, the current value
128
of \c {width*3} will be assigned to \c height as a \e static value. After that,
129
\e {the \c height will remain fixed at this value, even if the \c width changes}.
130
The assignment of the static value removes the binding.
131
132
\qml
133
import QtQuick 2.0
134
135
Rectangle {
136
width: 100
137
height: width * 2
138
139
focus: true
140
Keys.onSpacePressed: {
141
height = width * 3
142
}
143
}
144
\endqml
145
146
If the intention is to give the rectangle a fixed height and stop automatic
147
updates, then this is not a problem. However, if the intention is to establish
148
a new relationship between \c width and \c height, then the new binding
149
expression must be wrapped in the Qt.binding() function instead:
150
151
\qml
152
import QtQuick 2.0
153
154
Rectangle {
155
width: 100
156
height: width * 2
157
158
focus: true
159
Keys.onSpacePressed: {
160
height = Qt.binding(function() { return width * 3 })
161
}
162
}
163
\endqml
164
165
Now, after the space key is pressed, the rectangle's height will continue
166
auto-updating to always be three times its width.
167
168
\section3 Debugging overwriting of bindings
169
170
A common cause of bugs in QML applications is accidentally overwriting bindings
171
with static values from JavaScript statements. To help developers track down
172
problems of this kind, the QML engine is able to emit messages whenever a
173
binding is lost due to imperative assignments.
174
175
In order to generate such messages, you need to enable the informational output
176
for the \c{qt.qml.binding.removal} logging category, for instance by calling:
177
178
\code
179
QLoggingCategory::setFilterRules(QStringLiteral("qt.qml.binding.removal.info=true"));
180
\endcode
181
182
Please refer to the QLoggingCategory documentation for more information about
183
enabling output from logging categories.
184
185
Note that is perfectly reasonable in some circumstances to overwrite bindings.
186
Any message generated by the QML engine should be treated as a diagnostic aid,
187
and not necessarily as evidence of a problem without further investigation.
188
189
\section2 Using \c this with Property Binding
190
191
When creating a property binding from JavaScript, the \c this keyword can be used
192
to refer to the object which receives the binding. This is helpful for resolving
193
ambiguities with property names.
194
195
For example, the \c Component.onCompleted handler below is defined within the
196
scope of the \l Item. In this scope, \c width refers to the \l Item's width, not
197
the \l Rectangle's width. To bind the \l Rectangle's \c height to its own \c width,
198
the binding expression must explicitly refer to \c this.width (or alternatively,
199
\c{rect.width}):
200
201
\qml
202
Item {
203
width: 500
204
height: 500
205
206
Rectangle {
207
id: rect
208
width: 100
209
color: "yellow"
210
}
211
212
Component.onCompleted: {
213
rect.height = Qt.binding(function() { return this.width * 2 })
214
console.log("rect.height = " + rect.height) // prints 200, not 1000
215
}
216
}
217
\endqml
218
219
\note The value of \c this is not defined outside of property bindings.
220
See \l {JavaScript Environment Restrictions} for details.
221
*/
qtdeclarative
src
qml
doc
src
qmllanguageref
syntax
propertybinding.qdoc
Generated on
for Qt by
1.14.0