[Development] QProperty and library coding guide

Ulf Hermann ulf.hermann at qt.io
Fri Jul 17 21:35:06 CEST 2020


> Mhh, it there are no change signals anymore, i guess i also can't use
> QObject::connect() anymore and rather use a binding instead ? This is
> fine, but if two objects are living in different threads how does it
> work then ? With a Queued connection how it works with signals/slots is
> pretty clear, but in which thread is the binding evaluated ?

Binding properties from different threads is not supported. Bindings 
should be lightweight. Usually they'd be used for closely related bits 
of data. Those rarely live in different threads. Building thread 
synchronization into bindings would make them more expensive for little 
gain.

You can, however, still use queued signals in this scenario. QProperty 
has a subscribe() method, and if the change of a property is actually 
something you want to communicate across thread boundaries, you can 
attach a function that sends a signal to a QProperty via subscribe(). 
There is also QNotifiedProperty. I would advise against all of this, 
though. Sending the signal forces the property and everything it depends 
on to be eagerly evaluated. There likely are other ways to organize your 
thread synchronization.

> With the old properties it's also possible to define a custom behavior
> for the setter and getter. E.g. for the getter to not emit the changed
> signal, but just call a worker thread to to this and wait for the
> feedback to do the actual change and emit the change signal. I guess all
> this is not possibly anymore with the new QProperty ? If we define that
> behavior like this can not be done with QProperty but the old way should
> be used instead everything is fine, but doesn't make the API inconsistent ?

You get value guards with QNotifiedProperty, and soon also with 
QProperty: https://codereview.qt-project.org/c/qt/qtbase/+/307894
With those, you can introspect and/or modify a new value before it is 
set. You can do the additional work in a value guard, and you can even 
reject values that way. Using a value guard does not even force eager 
evaluation.

> As I understood it, we don't want to break SC too much so we will keep
> all setters/getters in our API.
> Let's say we create a new type derived from QQuickItem and use a
> QProperty there, let's name this property "foo".
> Doesn't it mean we now have a class, which has functions like setWidth
> and setHeight, but not a function for setFoo ?

Q_PRIVATE_QPROPERTY generates a setter, setFoo in this case, that just 
calls the setValue() function of the propery. If you add the property 
directly in the public object, you can do the same manually.

best,
Ulf


More information about the Development mailing list