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