On this page

C

Property bindings

You can assign a static value to an object's property, and it stays constant until you explicitly assign a new value. However, to make full use of QML and its built-in support for dynamic object behaviors, most QML objects use property bindings.

Property bindings are a core feature of QML that lets you specify relationships between different object properties. When a property's dependency changes its value, the property is updated according to the specified relationship.

Behind the scenes, the QML engine monitors the dependencies of a property (that is, the variables in the binding expression). When it detects a change, it re-evaluates the binding expression and applies the new result to the property.

Overview

To create a property binding, assign a JavaScript expression that evaluates to the desired value. A simplest version of this is a binding that refers to another property.

Bindings can access object properties, call methods, and use built-in JavaScript objects such as Math.

Note: As regards Qt Quick Ultralite applications, a binding can contain only a subset of JavaScript expressions or statements. For details, see JavaScript environment for Qt Quick Ultralite applications.

In the following example, the blue Rectangle's height is bound to the height of its parent:

Rectangle {
    width: 200; height: 200

    Rectangle {
        width: 100
        height: parent.height
        color: "blue"
    }
}

Whenever the height of the parent rectangle changes, the height of the blue rectangle updates to the same value.

The following is an example of other possible bindings for the previous example:

height: parent.height / 2

height: Math.min(parent.width, parent.height)

height: parent.height > 100 ? parent.height : parent.height/2

height: {
    if (parent.height > 100)
        return parent.height
    else
        return parent.height / 2
}

height: someMethodThatReturnsHeight()

The following is a more complex example that uses objects and types in a binding expression:

Column {
    id: column
    width: 200
    height: 200

    Rectangle {
        id: topRect
        width: Math.max(bottomRect.width, parent.width/2)
        height: (parent.height / 3) + 10
        color: "yellow"

        TextInput {
            id: myTextInput
            text: "Hello QML!"
        }
    }

    Rectangle {
        id: bottomRect
        width: 100
        height: 50
        color: myTextInput.text.length <= 10 ? "red" : "blue"
    }
}

In the previous example,

  • topRect.width depends on bottomRect.width and column.width
  • topRect.height depends on column.height
  • bottomRect.color depends on myTextInput.text.length

In addition, property references within a JavaScript function are re-evaluated if they are referring to their own values. For example, in the following snippet, whenever the enabled property of the Rectangle changes, the bindings for the x and y properties are re-evaluated:

Rectangle {
    x: rectPosition()
    y: rectPosition()
    width: 200
    height: 200
    color: "lightblue"

    function rectPosition() {
        return enabled ? 0 : 100
    }
}

Syntactically, bindings are allowed to be of arbitrary complexity. However, if a binding is overly complex - such as involving multiple lines, or imperative loops - it could indicate that the binding is doing more than describing property relationships.

Complex bindings can reduce the performance, readability, and maintainability of the code. In general, it's a good practice to redesign components that has complex bindings, or at least move the binding into a separate function. As a general rule, do not rely on the evaluation order of bindings.

Available under certain Qt licenses.
Find out more.