[Development] Property bindings in Qt 6

Pierre-Yves Siret py.siret at gmail.com
Thu Sep 26 20:03:02 CEST 2019


I feel like custom getters and the ability to mark a property dirty are
needed too.

You might have a property that's provided by an outside system, and you
maybe don't want to query it every time it changes, only when there's an
observer bound to that property.

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

Does it store a QString internally and modify it whenever surname &
lastname changes thus taking some space in memory or is it just evaluated
lazily and never stored?

In my projects I have some properties that are just computed from others
and not actually member variables.

Le jeu. 26 sept. 2019 à 17:46, Simon Hausmann <Simon.Hausmann at qt.io> a
écrit :

> Hi,
>
> Yeah, custom setters are required.
>
> One option would be to say that such properties are implemented using the
> traditional property system altogether — bridging will be necessary anyway.
>
> Another option would be to implement what you described, perhaps in a more
> convenient way though.
>
> Simon
>
> > On 26. Sep 2019, at 17:38, Mitch Curtis <mitch.curtis at qt.io> wrote:
> >
> > 
> >>
> >> -----Original Message-----
> >> From: Development <development-bounces at qt-project.org> On Behalf Of
> >> Simon Hausmann
> >> Sent: Thursday, 26 September 2019 5:03 PM
> >> To: development at qt-project.org
> >> Subject: [Development] Property bindings in Qt 6
> >>
> >> 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.
> >
> > I think you guys did an awesome job with it from what I've seen. :)
> >
> > In my experience with a similar system, one drawback is the lack of
> ability to implement custom setters. For example, I often find that I need
> to validate some input to a setter:
> >
> >
> https://code.qt.io/cgit/qt/qtquickcontrols2.git/tree/src/quicktemplates2/qquickslider.cpp#n355
> >
> > In the end the solution was to use "dirty events" (i.e. derive from a
> certain type, implement operator() and pass a pointer the property in its
> constructor) as a way of reacting to the changes after they were made, but
> this is not ideal.
> >
> > Will custom setters be possible?
> >
> >>
> >> Simon
> _______________________________________________
> Development mailing list
> Development at qt-project.org
> https://lists.qt-project.org/listinfo/development
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.qt-project.org/pipermail/development/attachments/20190926/4878feb9/attachment.html>


More information about the Development mailing list