Qt Bindable Properties

Qt provides bindable properties. Bindable properties are properties which either have a value or are specified using any C++ function, typically a C++ lambda expression. In case they are specified using a C++ function, they are updated automatically whenever their dependencies change.

Bindable properties are implemented in the class QProperty, which consists the data object and a pointer to a management data structure, and in class QObjectBindableProperty, which consists only of the data object and uses the encapsulating QObject to store the pointer to the management data structure.

Introductory Example

The binding expression computes the value by reading other QProperty values. Behind the scenes this dependency is tracked. Whenever a change in any property's dependency is detected, the binding expression is re-evaluated and the new result is applied to the property. This happens lazily, by marking the binding as dirty and evaluating it only when the property's value is requested. For example:

QProperty<QString> firstname("John");
QProperty<QString> lastname("Smith");
QProperty<int> age(41);

QProperty<QString> fullname;
fullname.setBinding([&]() { return firstname.value() + " " + lastname.value() + " age: " + QString::number(age.value()); });

qDebug() << fullname.value(); // Prints "John Smith age: 41"

firstname = "Emma"; // Marks binding expression as dirty

qDebug() << fullname.value(); // Re-evaluates the binding expression and prints "Emma Smith age: 41"

// Birthday is coming up
age.setValue(age.value() + 1);

qDebug() << fullname.value(); // Re-evaluates the binding expression and prints "Emma Smith age: 42"

When a new value is assigned to the firstname property, the binding expression for fullname is marked as dirty. So when the last qDebug() statement tries to read the name value of the fullname property, the expression is evaluated again, firstname() will be called again and return the new value.

Since bindings are C++ functions, they may do anything that's possible in C++. This includes calling other functions. If those functions access values held by QProperty, they automatically become dependencies to the binding.

Binding expressions may use properties of any type, so in the above example the age is an integer and folded into the string value using conversion to integer, but the dependency is fully tracked.

Tracking Bindable Properties

Sometimes the relationships between properties cannot be expressed using bindings. Instead you may need to run custom code whenever the value of a property changes and instead of assigning the value to another property, pass it to other parts of your application. For example writing data into a network socket or printing debug output. QProperty provides two mechanisms for tracking.

You can register for a callback function to be called whenever the value of a property changes, by using onValueChanged(). If you want the callback to also be called for the current value of the property, register your callback using subscribe() instead.

© 2021 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.