[Development] Property bindings in Qt 6

Eike Ziller Eike.Ziller at qt.io
Tue Oct 1 16:55:27 CEST 2019



> On 1. Oct 2019, at 16:12, Jason H <jhihn at gmx.com> wrote:
> 
> 
>> I’m all for a more declarative coding style also in C++.
>> I’m wondering if we are re-inventing part of Reactive Programing a la ReactiveX with QProperty, though?
>> 
>> The above looks similar to (sodium-cxx):
>> 
>>    cell_sink<QString> surname("John");
>>    cell_sink<QString> lastname("Smith”);
>>    cell<QString> fullname = surname.lift(
>>        lastname, [](QString s, QString l) { return s + " " + l; });
>> 
>>    qDebug() << fullname.sample();
>>    surname.send("Emma");
>>    qDebug() << fullname.sample();
>> 
>> or (RxJS):
>> 
>>    var surname = new BehaviorSubject("John");
>>    var lastname = new BehaviorSubject("Smith");
>>    var fullname = new BehaviorSubject();
>>    r.combineLatest(surname, lastname).pipe(map(([s, l]) => { return s + " " + l; })).subscribe(fullname);
>> 
>>    console.log(fullname.getValue());
>>    surname.next("Emma”);
>>    console.log(fullname.getValue());
>> 
>> What is the relation of QProperty to Reactive Programing, in which ways can we orient QProperty on what is done there, or learn from insights in that field?
> 
>> Using "fullname.listen([](QString s) { qDebug() << s; });" (or "fullname.subscribe(s => console.log(s));”) instead of the explicit logging in the example above
>> will print “John Smith”, whereas using change event listeners always requires special handling of the initial value.
> 
> I would (naively) think that this would be done by creating a default-constructed value, then setting it? 

Looks like I wasn’t clear with what I mean with this. The difference is


   cell_sink<QString> surname("John");
   cell_sink<QString> lastname("Smith”);
   cell<QString> fullname = surname.lift(
       lastname, [](QString s, QString l) { return s + " " + l; });

   fullname.listen([](QString s) { qDebug() << s; });
   surname.send("Emma”);

prints

John Smith
Emma Smith

(same for RxJS and subscribe),
whereas it looks like with the current patch for QProperty

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

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

   Qt::onPropertyChanged(fullname, [](QString s) { qDebug() << s; })
   surname = "Emma”;

prints just

Emma Smith

So you basically always have to write the special code that does whatever you want to do with the property when it changes, also with the initial value.
(sodium even has transactions, but that’s a different story ;) )

> So I've used knockout and observables, and at the same time used Qt, and I always preferred QML over the bindings with that framework.
> 
> I'm wondering (out loud) if we aren't kinda talking about a opposite of QGadget for our classes - one where it can just emit a changed() event for applicable setters. I'm not sure how much of moc would have to be brought in - obviously we wouldn't want it on every class...?

-- 
Eike Ziller
Principal Software Engineer

The Qt Company GmbH
Erich-Thilo-Straße 10
D-12489 Berlin
eike.ziller at qt.io
http://qt.io
Geschäftsführer: Mika Pälsi,
Juha Varelius, Mika Harjuaho
Sitz der Gesellschaft: Berlin, Registergericht: Amtsgericht Charlottenburg, HRB 144331 B



More information about the Development mailing list