QJSValue to json string (stringify) [Solved]
-
Is there a way to convert a QJSValue object to a json string?
What I'm trying to do:
Send a QVariant object formatted as a QJSValue object over a TCP connection from a TCP Service written using Qt 5.4 to a TCP client written using Qt 4.8.Problems:
Qt 4.8 does not have QJSValue objects. There is no easy was to create a json string from a QJSValue object.Plan:
Convert the QJSValue to a json string then send the message to the client. The client can then convert the json string back to a QVariant. -
Hi,
IIRC, there was an external module call QJson for Qt 4 that could be of interest.
Hope it helps
-
@bundickt said:
Is there a way to convert a QJSValue object to a json string?
Yes. QJsonDocument::toJson() produces a JSON string.
-
I don't have a QJsonDocument object. I have a QJSValue object. The QJSValue object is being created by the Qt Quick engine.
I create a Qt Quick plugin that creates a TCP server that allows the QML developers to send object to the connect clients:
c++
Q_INVOKABLE void sendMessage(QString clientId, QVariant data);
qml
sendMessage("client1", {key1: "value1", key2: "value2"});
data will be of type QJSValue.
-
@bundickt said:
I don't have a QJsonDocument object. I have a QJSValue object.
That's not a problem. We can convert it.
c++
Q_INVOKABLE void sendMessage(QString clientId, QVariant data);qml
sendMessage("client1", {key1: "value1", key2: "value2"});data will be of type QJSValue.
Notice that your
data
is inside a QVariant. So, use QJsonDocument::fromVariant() to create your JSON document, and then turn it into a string usingQJsonDocument::toJson()
. This works ifdata
is a JavaScript object or JavaScript array. -
Thanks for your help. The documentation for QJsonDocument says the QVariant must be one of the following types: QVariantMap, QVariantList or QStringList. However, the QVariant object I have is a QJSValue. I tested it and I get an invalid QJsonDocument. After doing a little experimentation I was able to get a JSON string.
Code:
void MyTcpServer::sendMessage(QString clientId, QVariant data) { QJsonDocument jsonDoc = QJsonDocument::fromVariant(data.value<QJSValue>().toVariant()); qDebug() << "json[" << jsonDoc.toJson() << "]"; ....
It looks like
data.value<QJSValue>().toVariant()
convert the QJSValue variant to a QVariantMap variant. -
You're welcome, and I'm glad you've found a solution.
The documentation for QJsonDocument says the QVariant must be one of the following types: QVariantMap, QVariantList or QStringList. However, the QVariant object I have is a QJSValue. I tested it and I get an invalid QJsonDocument.
...
It looks likedata.value<QJSValue>().toVariant()
convert the QJSValue variant to a QVariantMap variant.That's interesting. A QJSValue is simply a wrapper. If your QJSValue contains a JavaScript object, then it should already be stored as a QVariantMap.
Out of curiosity, could you run the following code and share the output?
void MyTcpServer::sendMessage(QString clientId, QVariant data) { qDebug() << data; ...
QJSValue stores the following datatypes like this:
- JavaScript boolean -> bool
- JavaScript number -> int/double
- JavaScript string -> QString
- JavaScript array -> QVariantList
- JavaScript object -> QVariantMap
- QObject -> QObject*
So, I expected your output to be:
QVariant(QVariantMap, QMap(("key1", QVariant(QString, "value1") ) ( "key2" , QVariant(QString, "value2") ) ) )
-
@bundickt said:
The output of
qDebug() << data;
is:QVariant(QJSValue, )
The output of
data.value<QJSValue>().toVariant()
is:QVariant(QVariantMap, QMap((key1, QVariant(QString, value1) ) ( key2 , QVariant(QString, value2) ) ) )
Ah, right. I thought the QML engine would automatically convert the QJSValue to a QVariantMap, but you had to do the conversion yourself.
Thank you for sharing your findings!