/**************************************************************************** ** ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the documentation of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:FDL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Free Documentation License ** 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. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** $QT_END_LICENSE$ ** ****************************************************************************/ /*! \page propertybinding.html \title Property Binding Property binding is a declarative way of specifying the value of a property. Binding allows a property's value to be expressed as an JavaScript expression that defines the value relative to other property values or data accessible in the application. The property value is automatically kept up to date if the other properties or data values change. Property bindings are created implicitly in QML whenever a property is assigned an JavaScript expression. The following QML uses two property bindings to connect the size of the rectangle to that of \c otherItem. \code Rectangle { width: otherItem.width height: otherItem.height } \endcode QML extends a standards compliant JavaScript engine, so any valid JavaScript expression can be used as a property binding. Bindings can access object properties, make function calls and even use builtin JavaScript objects like \e {Date} and \e {Math}. Assigning a constant value to a property can even be thought of as a binding - after all, a constant is a valid JavaScript expression! Here are some examples of more complex bindings: \code Rectangle { function calculateMyHeight() { return Math.max(otherItem.height, thirdItem.height); } anchors.centerIn: parent width: Math.min(otherItem.width, 10) height: calculateMyHeight() color: { if (width > 10) "blue"; else "red" } } \endcode While syntactically bindings can be of arbitrary complexity, if a binding starts to become overly complex - such as involving multiple lines, or imperative loops - it may be better to refactor the component entirely, or at least factor the binding out into a separate function. \section1 Changing Bindings The \l PropertyChanges element can be used within a state change to modify the bindings on properties. This example modifies the \l Rectangle's width property binding to be \c {otherItem.height} when in the "square" state. When it returns to its default state, width's original property binding will have been restored. \code Rectangle { id: rectangle width: otherItem.width height: otherItem.height states: State { name: "square" PropertyChanges { target: rectangle width: otherItem.height } } } \endcode \section1 Binding Properties from JavaScript When working with both QML and JavaScript, it is important to differentiate between \l {Property Binding} syntax in QML and simple \e {property assignment} in JavaScript. Take the example below, which uses property binding to ensure the item's \c height is always twice its \c width: \qml Item { width: 100 height: width * 2 } \endqml On the other hand, take the following JavaScript code snippet, which \e assigns, rather than \e binds, the value of the \c height property: \code Item { width: 100 Component.onCompleted: { height = width * 2 // if width changes later, height is not updated! } } \endcode Instead of creating a property binding, this simply sets the \c height property to the correct value \e {at the time that} the JavaScript code is invoked. Unlike the first example, the \c height will never change if \c width changes. The \e {property : value} syntax for property binding is QML-specific and cannot be used in JavaScript. Instead, to bind a property from JavaScript, assign a \e function to the property that returns the required value. The following code correctly sets the property binding created in the first example, but creates the binding in JavaScript rather than QML: \qml Item { width: 100 Component.onCompleted: { height = (function() { return width * 2 }) } } \endqml \section2 Using \c this to create a binding When creating a property binding from JavaScript, QML allows the use of the \c this keyword to refer to the object to which the property binding will be assigned. This allows one to explicitly refer to a property within an object when there may be ambiguity about the exact property that should be used for the binding. For example, the \c Component.onCompleted handler below is defined within the scope of the \l Item, and references to \c width within this scope would refer to the \l Item's width, rather than that of the \l Rectangle. To bind the \l Rectangle's \c height to its own \c width, the function needs to explicitly refer to \c this.width rather than just \c width. Otherwise, the height of the \l Rectangle would be bound to the width of the \l Item and not the \l Rectangle. \qml Item { width: 500 height: 500 Rectangle { id: rect width: 100 color: "yellow" } Component.onCompleted: { rect.height = (function() { return this.width * 2 }) } } \endqml (In this case, the function could also have referred to \c rect.width rather than \c this.width.) Note that the value of \c this is not defined outside of its use in property binding. See \l {QML JavaScript Restrictions} for details. \section2 Effects of property assignment Note that assigning a value to a property that is currently bound will remove the binding. A property can only have one value at a time, and if any code explicitly sets this value, the binding is removed. In the following example, although \c width has been bound to \c height, the binding is removed by the JavaScript code that assigns \c width to 50: \code Item { width: height * 2 height: 100 Component.onCompleted: { width = 50; } } \endcode \section1 The Binding Element The implicit binding syntax shown previously is easy to use and works perfectly for most uses of bindings. In some advanced cases, it is necessary to create bindings explicitly using the \l Binding element. For example, to bind a property exposed from C++ (\c system.brightness) to a value coming from QML (\c slider.value), you could use the Binding element as follows: \qml Binding { target: system property: "brightness" value: slider.value } \endqml */