How to create/read/write JSON files in Qt5
Example: Read json from file
/* test.json */{ "appDesc": { "description": "SomeDescription", "message": "SomeMessage" }, "appName": { "description": "Home", "message": "Welcome", "imp":["awesome","best","good"] }}void readJson() { QString val; QFile file; file.setFileName("test.json"); file.open(QIODevice::ReadOnly | QIODevice::Text); val = file.readAll(); file.close(); qWarning() << val; QJsonDocument d = QJsonDocument::fromJson(val.toUtf8()); QJsonObject sett2 = d.object(); QJsonValue value = sett2.value(QString("appName")); qWarning() << value; QJsonObject item = value.toObject(); qWarning() << tr("QJsonObject of description: ") << item; /* in case of string value get value and convert into string*/ qWarning() << tr("QJsonObject[appName] of description: ") << item["description"]; QJsonValue subobj = item["description"]; qWarning() << subobj.toString(); /* in case of array get array and convert into string*/ qWarning() << tr("QJsonObject[appName] of value: ") << item["imp"]; QJsonArray test = item["imp"].toArray(); qWarning() << test[1].toString(); }
OUTPUT
QJsonValue(object, QJsonObject({"description": "Home","imp": ["awesome","best","good"],"message": "YouTube"}) ) "QJsonObject of description: " QJsonObject({"description": "Home","imp": ["awesome","best","good"],"message": "YouTube"}) "QJsonObject[appName] of description: " QJsonValue(string, "Home") "Home" "QJsonObject[appName] of value: " QJsonValue(array, QJsonArray(["awesome","best","good"]) ) "best"
Example: Read json from string
Assign json to string as below and use the readJson()
function shown before:
val = ' { "appDesc": { "description": "SomeDescription", "message": "SomeMessage" }, "appName": { "description": "Home", "message": "Welcome", "imp":["awesome","best","good"] } }';
OUTPUT
QJsonValue(object, QJsonObject({"description": "Home","imp": ["awesome","best","good"],"message": "YouTube"}) ) "QJsonObject of description: " QJsonObject({"description": "Home","imp": ["awesome","best","good"],"message": "YouTube"}) "QJsonObject[appName] of description: " QJsonValue(string, "Home") "Home" "QJsonObject[appName] of value: " QJsonValue(array, QJsonArray(["awesome","best","good"]) ) "best"
Sadly, many JSON C++ libraries have APIs that are non trivial to use, while JSON was intended to be easy to use.
So I tried jsoncpp from the gSOAP tools on the JSON doc shown in one of the answers above and this is the code generated with jsoncpp to construct a JSON object in C++ which is then written in JSON format to std::cout:
value x(ctx);x["appDesc"]["description"] = "SomeDescription";x["appDesc"]["message"] = "SomeMessage";x["appName"]["description"] = "Home";x["appName"]["message"] = "Welcome";x["appName"]["imp"][0] = "awesome";x["appName"]["imp"][1] = "best";x["appName"]["imp"][2] = "good";std::cout << x << std::endl;
and this is the code generated by jsoncpp to parse JSON from std::cin and extract its values (replace USE_VAL
as needed):
value x(ctx);std::cin >> x;if (x.soap->error) exit(EXIT_FAILURE); // error parsing JSON#define USE_VAL(path, val) std::cout << path << " = " << val << std::endlif (x.has("appDesc")){ if (x["appDesc"].has("description")) USE_VAL("$.appDesc.description", x["appDesc"]["description"]); if (x["appDesc"].has("message")) USE_VAL("$.appDesc.message", x["appDesc"]["message"]);}if (x.has("appName")){ if (x["appName"].has("description")) USE_VAL("$.appName.description", x["appName"]["description"]); if (x["appName"].has("message")) USE_VAL("$.appName.message", x["appName"]["message"]); if (x["appName"].has("imp")) { for (int i2 = 0; i2 < x["appName"]["imp"].size(); i2++) USE_VAL("$.appName.imp[]", x["appName"]["imp"][i2]); }}
This code uses the JSON C++ API of gSOAP 2.8.28. I don't expect people to change libraries, but I think this comparison helps to put JSON C++ libraries in perspective.
JSON under QT is actually quite pleasant - I was surprised. This is an example of how to create a JSON output with some structure.
Forgive me for not explaining what the fields all mean - it is a Ham Radio processing output script.
This is the QT C++ Code
void CabrilloReader::JsonOutputMapper(){ QFile file(QDir::homePath() + "/1.json"); if(!file.open(QIODevice::ReadWrite)) { qDebug() << "File open error"; } else { qDebug() <<"JSONTest2 File open!"; } // Clear the original content in the file file.resize(0); // Add a value using QJsonArray and write to the file QJsonArray jsonArray; for(int i = 0; i < 10; i++) { QJsonObject jsonObject; CabrilloRecord *rec= QSOs.at(i); jsonObject.insert("Date", rec->getWhen().toString()); jsonObject.insert("Band", rec->getBand().toStr()); QJsonObject jsonSenderLatObject; jsonSenderLatObject.insert("Lat",rec->getSender()->fLat); jsonSenderLatObject.insert("Lon",rec->getSender()->fLon); jsonSenderLatObject.insert("Sender",rec->getSender_call()); QJsonObject jsonReceiverLatObject; jsonReceiverLatObject.insert("Lat",rec->getReceiver()->fLat); jsonReceiverLatObject.insert("Lon",rec->getReceiver()->fLon); jsonReceiverLatObject.insert("Receiver",rec->getReceiver_call()); jsonObject.insert("Receiver",jsonReceiverLatObject); jsonObject.insert("Sender",jsonSenderLatObject); jsonArray.append(jsonObject); QThread::sleep(2); } QJsonObject jsonObject; jsonObject.insert("number", jsonArray.size()); jsonArray.append(jsonObject); QJsonDocument jsonDoc; jsonDoc.setArray(jsonArray); file.write(jsonDoc.toJson()); file.close(); qDebug() << "Write to file";}
It takes an internal QT Structure (a List of pointers to a CabrilloRecord object ... which you just ignore) and extracts some fields. These fields are then output in a nested JSON format which looks like this.
[ { "Band": "20", "Date": "Sat Jul 10 12:00:00 2021", "Receiver": { "Lat": 36.400001525878906, "Lon": 138.3800048828125, "Receiver": "8N3HQ " }, "Sender": { "Lat": 13, "Lon": 122, "Sender": "DX0HQ " } }, { "Band": "20", "Date": "Sat Jul 10 12:01:00 2021", "Receiver": { "Lat": 36.400001525878906, "Lon": 138.3800048828125, "Receiver": "JA1CJP " }, "Sender": { "Lat": 13, "Lon": 122, "Sender": "DX0HQ " } }]
I hope this speeds up someone else's progression on this topic.