[Development] QVariant container API

Arnaud Clère arnaud.clere at minmaxmedical.com
Wed Apr 3 00:16:23 CEST 2019


Hi,

I have a proposal to drastically reduce this kind of boilerplate code which I call "QBind". When I presented it last year to QtCS it was not mature enough but it know exhibits very good performance and convenience for this kind of use case.

Maybe you can have a look at QBind benchmark's main.cpp to see if the approach can suit your need :
https://gricad-gitlab.univ-grenoble-alpes.fr/modmed/modmedLog/blob/master/tests/QBind/main.cpp
#L67 defines a struct Person with internal bind method (it can be external too)

>From them on, you can Read/Write a Person in various ways in a single line of code:
#L431 to QVariant container
#L436 to Cbor buffer (3x faster)
#L581 from Cbor buffer (with read errors)
#L693 to QTreeView or QTableView using a QStandardItemModel and providing some metadata
https://gricad-gitlab.univ-grenoble-alpes.fr/modmed/modmedLog/blob/master/tests/QBind/qstandardmodel.PNG

Using QVariant as an intermediate data structure is not optimal to read/write your QList<MyStruct>:
- dynamic allocations will significantly limit the write performance, see my benchmark that writes various tracepoint payloads to a QVariant container vs Cbor and Json buffers
https://gricad-gitlab.univ-grenoble-alpes.fr/modmed/modmedLog/blob/master/tests/QBind/write.PNG
- it also prevents from directly using the QList<MyStruct> type to guide the deserialization. In QBind you do not need to register types at runtime and you avoid losing data silently (instead you have static_asserts complaining at compile time).

Arnaud Clère


________________________________
From: Vasily Pupkin <shkodindanil.letmework at gmail.com>
Sent: 01 April 2019 15:44
To: Thiago Macieira
Cc: development at qt-project.org
Subject: Re: [Development] QVariant container API

> By the way, conversions through QVariant are *exactly* what I implemented in
> the examples/corelib/serialization/convert tool.

Right, I've seen these to be helpful.

The global task would allow to code like this.
~
struct MyStruct
{
    int property1;
    QString property2;
};

class MyObject
{
    Q_OBJECT
    ...
public slots:
    void mySlot(const QList<MyStruct>& value);
}

QJsonDocument doc(...);

QMetaMethod mySlot(...);

JsonDeserializer deserializer;

QVariant parameter;
if(deserializer.deserialize(doc,  mySlot.paremeterType(0), parameter)
    invoke(...);
else
{
    //error
}
~

The only difference from examples, is that library user specifies, what datatype should be produced. This would alllow to significantly reduce the amount of boilerplate code.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.qt-project.org/pipermail/development/attachments/20190402/5eedb151/attachment.html>


More information about the Development mailing list