Finn
Finn

Reputation: 1459

qml parsing QVariant QJsonDocument to js object

A QVariant I took from C++ contains a QJsonDocument, and I want to convert it to a js object, but I only found the use of QJsonDocument in C++. I couldn't find how to use QJsonDocument in qml.

For Example:

Qml:

function qmlUpdateObject( Object ){
   console.log(Object);
}

// console content: qml: QVariant(QJsonDocument, QJsonDocument({"appDesc":{"description":"SomeDescription","message":"SomeMessage"},"appName":{"description":"Home","imp":["awesome","best","good"],"message":"Welcome"}}))

// I want to get a js object: {"appDesc":{"description":"SomeDescription","message":"SomeMessage"},"appName":{"description":"Home","imp":["awesome","best","good"],"message":"Welcome"}}

C++:

QObject::connect( this, SIGNAL( updateData(QVariant)),
                  viewItem, SLOT( qmlUpdateObject(QVariant)) );

void Controller::setData(QString name)
{
 QFile file("data.json");
 QJsonDocument d = QJsonDocument::fromJson(file.readAll()); 
 QByteArray dataJson = d.toJson(QJsonDocument::Compact);
 emit updateData(dataJson);
}

UPDATE Add this line and pass back, qml can successfully parse:

QByteArray dataJson = d.toJson(QJsonDocument::Compact);

Upvotes: 1

Views: 1479

Answers (1)

eyllanesc
eyllanesc

Reputation: 244291

There is no direct QJsonDocument conversion to a js object. One possible solution is to convert the QJsonDocument to QByteArray and export it to QML, and in QML do parse using JSON.parse():

C++

QByteArray dataJson = doc.toJson(QJsonDocument::Compact);
// send dataJson to QML

QML

var json = JSON.parse(dataJson)

Note:

  • It seems that the OP does not know the good practice of not accessing QML objects from C++ but must create a QObject and export it to QML.

  • The example provided by the OP is not necessary to use QJsonDocument since JSON.parse() does the same as QJsonDocument d = QJsonDocument::fromJson(file.readAll());.

#include <QFile>
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>

class Controller: public QObject{
    Q_OBJECT
public:
    void setData(const QString & filename){
        QFile file(filename);
        if(file.open(QIODevice::ReadOnly))
            Q_EMIT updateData(file.readAll());
    }
Q_SIGNALS:
    void updateData(const QByteArray & data);
};

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

    QGuiApplication app(argc, argv);

    Controller controller;

    QQmlApplicationEngine engine;
    engine.rootContext()->setContextProperty("controller", &controller);
    const QUrl url(QStringLiteral("qrc:/main.qml"));
    QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
                     &app, [url](QObject *obj, const QUrl &objUrl) {
        if (!obj && url == objUrl)
            QCoreApplication::exit(-1);
    }, Qt::QueuedConnection);
    engine.load(url);
    controller.setData("data.json");

    return app.exec();
}
#include "main.moc"
import QtQuick 2.14
import QtQuick.Window 2.14

Window {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")

    function qmlUpdateObject( data ){
        var obj = JSON.parse(data)
        console.log(obj);
    }
    Connections{
        target: controller
        onUpdateData: qmlUpdateObject(data)
    }
}

Upvotes: 2

Related Questions