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