Hi,

Earlier this year, Olivier, Samuel, Auri and I worked on a project to 
re-evaluate how we could bring the declarative Qt Quick approach of doing user 
interfaces closer to C++, in order to allow building and running user 
interfaces in very memory and processor-power constrained environments. There 
were many different outcomes of this. One of them was that we figured out a way 
to compile QML binding expressions down to full C++, without any run-time 
interpretation. This required building a new way of defining properties and 
their relationships, a new property binding system. The results were so 
convincing that the plan was born to productize this for Qt 6 in multiple 
layers and steps. I'd like to initiate a first step in that direction by 
proposing API and functionality for Qt 6 and briefly outline how we see the 
building blocks apply to QML and Qt Quick:

In QML, today, properties consist of a type, a setter function and a getter 
function, and the functions are implemented by the developer. There is also a 
change signal that needs to be emitted when the value changes.

Binding expressions declared in .qml files are created behind the scenes and 
the QML engine makes sure to call the getter functions during the evaluation 
and the setter function to write the result. Through a connection to the change 
signal, bindings are automatically re-evaluated when properties change and the 
new values are passed to the setter functions. It's pretty magic and it works, 
but it requires a fair amount of indirection and side-loading of data 
structures.

I would like to propose an API that replaces the setter and getter functions on 
objects with a new property template class that encapsulates the property value 
instead, and the ability to tie binding expressions to these properties for 
automatic updates. In short, it looks like this:

    QProperty<QString> surname("John");
    QProperty<QString> lastname("Smith");

    QProperty<QString> fullname;
    fullname.setBinding([&]() { return surname() + " " + lastname(); });

    qDebug() << fullname(); // Prints "John Smith"

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

    qDebug() << fullname(); // Re-evaluates the binding expression and prints 
"Emma Smith"


You can see a work-in-progress patch for this in Gerrit at

    https://codereview.qt-project.org/c/qt/qtbase/+/275352


The basic data structure behind this is the property value itself as well as 
doubly linked lists to track dependencies between properties and binding 
expressions. Due to the encapsulation of the data itself in a class, it is 
possible to do a lazy evaluation of bindings. (Credit goes in particular to 
Olivier for the idea and first implementation in our project)


Once this class and its documentation is complete, the next step is to build a 
bridge to the QML engine and the moc, so that it's possible to associate 
binding expressions in .qml files with properties declared this way. Similarly, 
it needs to be possible to access such properties through the meta-call, if 
they are placed inside Q_OBJECT classes.

The next step is to begin applying this to the implementation of Qt Quick. Some 
of which may require shims for the public Qt Quick API (to keep it Q_PROPERTY 
based), and for the private Qt Quick types the idea would be to start using 
QProperty.

Finally, once all the pieces are in place, we hope to extend the qml tooling to 
compile the binding expressions in .qml files to C++ that uses this more 
light-weight property system whenever possible. Ulf has been working towards 
this from the QML engine direction (see the recent email about moc and 
meta-type extraction) and Fabian has been working on the QML linter as a 
starting point towards a compilation model for QML.


This is our rough plan of how we'd like to address one aspect of QML and Qt 
Quick today. We are looking forward to any feedback and questions to help us 
review and refine this design.


Simon
_______________________________________________
Development mailing list
Development@qt-project.org
https://lists.qt-project.org/listinfo/development

Reply via email to