I need to parse JSON object through Qt. What is the easiest/fastest way to do it?
-
See [Best JSON parser for Qt? ](http://stackoverflow.com/questions/1825892?tab=newest#tab-top). – Matthew Flaschen Nov 12 '10 at 23:44
-
3Looks like Qt5 has some JSON classes. http://qt-project.org/doc/qt-5.0/qtcore/json.html – Jared Price Nov 05 '13 at 17:30
-
http://stackoverflow.com/questions/4987560/how-to-serialize-to-json-in-qt/16174375 – dtech Jun 08 '14 at 18:22
6 Answers
JSON parsing is now supported in Qt 5. Here's how to load and parse a document:
#include <QByteArray>
#include <QFile>
#include <QJsonObject>
#include <QJsonDocument>
// ...
// Read JSON file
QFile file("/path/to/file.json");
file.open(QIODevice::ReadOnly);
QByteArray rawData = file.readAll();
// Parse document
QJsonDocument doc(QJsonDocument::fromJson(rawData));
// Get JSON object
QJsonObject json = doc.object();
// Access properties
qDebug() << json["something"].toString();

- 88,262
- 77
- 290
- 428
Try QJson.
QJson is actively developed (and used by KDE, if I'm not mistaken). The best is to checkout the source code directly and built it yourself. There is no dependencies to QJson (except for Qt and CMake). It's pretty simple to use too, have a look at some usage examples :

- 4,808
- 3
- 29
- 44

- 4,681
- 6
- 32
- 46
Here is Qt style json encoder/decoder
#include "json.h"
#include <QScriptEngine>
#include <QScriptValueIterator>
Json::Json()
{
}
QString Json::encode(const QMap<QString,QVariant> &map)
{
QScriptEngine engine;
engine.evaluate("function toString() { return JSON.stringify(this) }");
QScriptValue toString = engine.globalObject().property("toString");
QScriptValue obj = encodeInner(map, &engine);
return toString.call(obj).toString();
}
QMap<QString, QVariant> Json::decode(const QString &jsonStr)
{
QScriptValue object;
QScriptEngine engine;
object = engine.evaluate("(" + jsonStr + ")");
return decodeInner(object);
}
QScriptValue Json::encodeInner(const QMap<QString,QVariant> &map, QScriptEngine* engine)
{
QScriptValue obj = engine->newObject();
QMapIterator<QString, QVariant> i(map);
while (i.hasNext()) {
i.next();
if (i.value().type() == QVariant::String)
obj.setProperty(i.key(), i.value().toString());
else if (i.value().type() == QVariant::Int)
obj.setProperty(i.key(), i.value().toInt());
else if (i.value().type() == QVariant::Double)
obj.setProperty(i.key(), i.value().toDouble());
else if (i.value().type() == QVariant::List)
obj.setProperty(i.key(), qScriptValueFromSequence(engine, i.value().toList()));
else if (i.value().type() == QVariant::Map)
obj.setProperty(i.key(), encodeInner(i.value().toMap(), engine));
}
return obj;
}
QMap<QString, QVariant> Json::decodeInner(QScriptValue object)
{
QMap<QString, QVariant> map;
QScriptValueIterator it(object);
while (it.hasNext()) {
it.next();
if (it.value().isArray())
map.insert(it.name(),QVariant(decodeInnerToList(it.value())));
else if (it.value().isNumber())
map.insert(it.name(),QVariant(it.value().toNumber()));
else if (it.value().isString())
map.insert(it.name(),QVariant(it.value().toString()));
else if (it.value().isNull())
map.insert(it.name(),QVariant());
else if(it.value().isObject())
map.insert(it.name(),QVariant(decodeInner(it.value())));
}
return map;
}
QList<QVariant> Json::decodeInnerToList(QScriptValue arrayValue)
{
QList<QVariant> list;
QScriptValueIterator it(arrayValue);
while (it.hasNext()) {
it.next();
if (it.name() == "length")
continue;
if (it.value().isArray())
list.append(QVariant(decodeInnerToList(it.value())));
else if (it.value().isNumber())
list.append(QVariant(it.value().toNumber()));
else if (it.value().isString())
list.append(QVariant(it.value().toString()));
else if (it.value().isNull())
list.append(QVariant());
else if(it.value().isObject())
list.append(QVariant(decodeInner(it.value())));
}
return list;
}

- 91
- 1
- 1
-
This looks very nice... but does not compile... undefined reference to QScriptEngine::newObject ...... and I added #include
in the json.h file. Is it even possible to use this with QT 4.8.1. ? – user568021 Dec 16 '13 at 19:51 -
-
Awesome solution! It would be a nice header-only library, just include-and-use rather all the all build library thing with infinite dependences. Something to turn that QMap into an object would make it perfect. I managed to do that I'll leave the code here to be used with your code. – Jack Sep 12 '17 at 03:24
If you don't want to depend on external libraries you could use the QScriptEngine
http://qtwiki.remdex.info/Parsing_JSON_with_QT_using_standard_QT_library

- 7,412
- 4
- 32
- 52

- 1,604
- 14
- 21
I know this answer is late, but I recently created a project to help create code which is meant to compile on both Qt4 and Qt5 and deals with JSON.
https://code.google.com/p/qjson4/
This library is indented to be a drop in replacement for QJsonDocument
in Qt4 and will use Qt's classes when used in Qt5. So it should be a fairly smooth transition. It's not 100% complete, but the major features are in there :-).

- 87,561
- 32
- 179
- 238
-
Great answer which I have upvoted. Just a small addition to your code in `QJsonValue.h`: `Q_DECLARE_METATYPE(QJsonValue)` to make this class usable in some special cases. – jonathanzh Mar 25 '16 at 16:12
-
I would recommend qjson-backport, as it uses the same API as in Qt5.
You can conditionally load the library when you use Qt4, and use the default implementation when using Qt5.
My qjson.pri
file looks like:
!greaterThan(QT_MAJOR_VERSION, 4): {
INCLUDEPATH += \
$$PWD
SOURCES += \
$$PWD/qjson.cpp \
$$PWD/qjsonarray.cpp \
$$PWD/qjsondocument.cpp \
$$PWD/qjsonobject.cpp \
$$PWD/qjsonparser.cpp \
$$PWD/qjsonvalue.cpp \
$$PWD/qjsonwriter.cpp
HEADERS += \
$$PWD/qjson_p.h \
$$PWD/qjsonarray.h \
$$PWD/qjsondocument.h \
$$PWD/qjsonobject.h \
$$PWD/qjsonparser_p.h \
$$PWD/qjsonvalue.h \
$$PWD/qjsonwriter_p.h
}

- 861
- 9
- 22