Showing posts with label HTTP. Show all posts
Showing posts with label HTTP. Show all posts

Friday, July 17, 2020

Serialize/Deserialize JSON Representations to Qt Objects (QObject's) in C++

Calls to HTTP servers are very frequent nowadays, and JSON is frequently used when dealing with structured data. When I write applications in Java/Kotlin, I always use retrofit2 with gson integration, or similar approaches. It is very comfortable to be able to serialize/deserialize to Java objects automatically. I tried to find something similar for Qt, but I couldn't find much. JSON support in Qt is good, but does not seem to be able to map QOject's to QJSonObject. I also could not find other C++ libraries doing this. Probably the difficulty of implementing reflection in C++ would make the implementation a bit convoluted. A good candidate I found is this: https://github.com/Loki-Astari/ThorsSerializer, which seems not to require much boilerplate code, not too verbose and no generated code.

However, Qt includes the meta object system (https://doc.qt.io/qt-5/metaobjects.html), and therefore I tried to use it to get the desired result. In a couple of hours I got to a pretty decent result: https://github.com/carlonluca/lqobjectserializer. It is far from perfect, but it seems to work. Have a look at the readme or the unit tests to know more.
The draft is free to use: you can contribute, report bugs etc...

For instance, a JSON object like this:

{"menu": {
    "header": "SVG Viewer",
    "items": [
        {"id": "Open"},
        {"id": "OpenNew", "label": "Open New"},
        null,
        {"id": "ZoomIn", "label": "Zoom In"},
        {"id": "ZoomOut", "label": "Zoom Out"},
        {"id": "OriginalView", "label": "Original View"},
        null,
        {"id": "Quality"},
        {"id": "Pause"},
        {"id": "Mute"},
        null,
        {"id": "Find", "label": "Find..."},
        {"id": "FindAgain", "label": "Find Again"},
        {"id": "Copy"},
        {"id": "CopyAgain", "label": "Copy Again"},
        {"id": "CopySVG", "label": "Copy SVG"},
        {"id": "ViewSVG", "label": "View SVG"},
        {"id": "ViewSource", "label": "View Source"},
        {"id": "SaveAs", "label": "Save As"},
        null,
        {"id": "Help"},
        {"id": "About", "label": "About Adobe CVG Viewer..."}
    ]
}}

can be deserialized to a QObject simply by defining the classes (macros here are inherited by my other project https://github.com/carlonluca/lqtutils, but this is not mandatory):

L_BEGIN_CLASS(Item)
L_RW_PROP(QString, id, setId, QString())
L_RW_PROP(QString, label, setLabel, QString())
L_END_CLASS

L_BEGIN_CLASS(Menu)
L_RW_PROP(QString, header, setHeader)
L_RW_PROP_ARRAY_WITH_ADDER(Item*, items, setItems)
L_END_CLASS

L_BEGIN_CLASS(MenuRoot)
L_RW_PROP(Menu*, menu, setMenu, nullptr)
L_END_CLASS

and by writing these few lines:

LDeserializer<MenuRoot> deserializer(factory);
QScopedPointer<MenuRoot> g(deserializer.deserialize(jsonString));

Please leave a comment if you know of other tools in this context, serializing and deserializing JSON is very frequent.
Bye! ;-)

Monday, June 27, 2016

Streaming from VLC to a Qt App on HTTP Using POT

The latest version of POT (5.3.0-beta1) implements some kind of buffering which makes it also possible to do some streaming. ffmpeg provides what is needed to work on protocols like HTTP. This video is a little demo showing how simple it is to stream from VLC on HTTP, remuxing to mpeg-ts, and decoding/rendering on Raspberry Pi in an accelerated Qt application using POT.
Such feature can be useful when dealing with streams coming from many sources, like an IP camera for instance.
Have fun! Bye ;-)