74

Qt5 has a new JSON parser and I want to use it. The problem is that it isn't too clear about what the functions do in layman's terms and how to write code with it. That or I could be reading it wrong.

I want to know the code on creating a JSON file in Qt5 and what "encapsulates" mean.

Joshua Wade
  • 4,755
  • 2
  • 24
  • 44
Jim Kieger
  • 901
  • 1
  • 8
  • 13
  • http://qjson.sourceforge.net/ – Min Lin Apr 09 '13 at 04:45
  • Min Lin: QJson is sort of outdated with Qt5 (not sure it's even ported), as it brings its own Json implementation. Jim Kieger: What have you tried? – Frank Osterfeld Apr 09 '13 at 11:50
  • [This reference page](https://qt-project.org/doc/qt-5.0/qtcore/qjsondocument.html) has the QJsonDocument::QJsonDocument() and QJsonDocument::QJsonDocument(const QJsonDocument & other) functions. I've tried QJsonDocument but it doesn't seem to create anything. – Jim Kieger Apr 09 '13 at 14:48

4 Answers4

119

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" 
eddie
  • 1,252
  • 3
  • 15
  • 20
Umasankar Natarajan
  • 1,334
  • 1
  • 9
  • 6
  • I found this really good example a bright shiny star of hope and have followed the example to the letter. However, when I debug the example, the values of the entries are showing as null. Is this the only example "step by step" on how to create, read and write a JSON file in QT? I can't figure out what I might be doing wrong. Using QT Creator 3.0.1. Thanks – Shawn Mar 11 '14 at 01:39
  • 1
    @Shawn In the Help tab in QT Creator, search for JSON Save Game Example. This pretty much demonstrates everything one needs to do to read and write JSON values (including arrays). [JSON Save Game Example](http://qt-project.org/doc/qt-5/qtcore-savegame-example.html) – Vikas Bhargava Mar 20 '14 at 13:19
  • You could skip converting utf-8 bytes to utf-16 and back (QString, `toUtf8()`) if you use `QByteArray` instead. – jfs May 02 '17 at 20:48
  • Load whole file to string and then parse the string, really?! – Youda008 Nov 22 '17 at 08:36
  • I was having trouble with this until I checked the optional error parameter: `QJsonParseError err; QByteArray utf8String = jsonString.toUtf8(); QJsonDocument d = QJsonDocument::fromJson(utf8String, &err);` – Pescolly Jan 30 '20 at 04:17
  • How to create/read/write JSon files in Qt5 is not answered - at least today is there just a read example or am I wrong? – Ingo Mi Apr 08 '20 at 02:20
  • If I compile SQLite3 with the JSON1 extension, can I use the JSON1 extension in Qt 4.10? – Benjamin Levy Jun 10 '20 at 16:19
4

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.

Tim Seed
  • 5,119
  • 2
  • 30
  • 26
2

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::endl
if (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.

Dr. Alex RE
  • 1,772
  • 1
  • 15
  • 23
1

An example on how to use that would be great. There is a couple of examples at the Qt forum, but you're right that the official documentation should be expanded.

QJsonDocument on its own indeed doesn't produce anything, you will have to add the data to it. That's done through the QJsonObject, QJsonArray and QJsonValue classes. The top-level item needs to be either an array or an object (because 1 is not a valid json document, while {foo: 1} is.)

parsley72
  • 8,449
  • 8
  • 65
  • 98
Jan Kundrát
  • 3,700
  • 1
  • 18
  • 29
  • 1
    After looking into this, I think I'm gonna stay with QSettings instead of using JSon for certain things. Thanks for your help. – Jim Kieger Apr 12 '13 at 14:42