13

I am trying to learn how to use JSON and the Qt JSON classes. For example I wnat to create a simple QJsonDocument, save it to a file, load it into a different QJsonDocument and compare results.

I managed to create a QJsonDocument. However there is no simple command in the QJsonDocument interface to save it to a file. The same goes for loading the document from a file.

#include <QJsonObject>
#include <QJsonDocument>
#include <QVariant>

int main()
{
    QVariantMap map;
    map.insert("integer", 1);
    map.insert("double", 2.34);
    map.insert("bool", QVariant(true));
    map.insert("string", "word");
    QJsonObject object = QJsonObject::fromVariantMap(map);

    QJsonDocument document;
    document.setObject(object);

    // ?? save document to file
    // ?? load file to document

    return 0;
}

This answer shows how to load the document by

  1. reading to a QFile
  2. converting QFile to a QString
  3. converting the QString to a QByteArray
  4. constructing the QJsonDocument from the QByteArray

Is there a more straightforward way to do this?

Community
  • 1
  • 1
Martin Drozdik
  • 12,742
  • 22
  • 81
  • 146

2 Answers2

51

Personally, I think that code [that you linked to] looks a bit messy. Warning: head compiled code follows.

QJsonDocument loadJson(QString fileName) {
    QFile jsonFile(fileName);
    jsonFile.open(QFile::ReadOnly);
    return QJsonDocument().fromJson(jsonFile.readAll());
}

void saveJson(QJsonDocument document, QString fileName) {
    QFile jsonFile(fileName);
    jsonFile.open(QFile::WriteOnly);
    jsonFile.write(document.toJson());
}

This may not be perfect: it assumes QFile instead of QIODevice, but if you're dealing with only local files maybe it won't matter. You can then use these functions instead of repeating the Json load/save code everytime you need to load/save Json.

John Chadwick
  • 3,193
  • 19
  • 19
  • Thank you! The two answers are equally valuable to me – Martin Drozdik Jan 21 '14 at 15:45
  • I learn by example a lot quicker personally, so I like this answer _more_, but yeah, they're both quite good! – kayleeFrye_onDeck Jan 04 '17 at 23:03
  • 2
    From a memory point of view this is not the best, because the json is first loaded from file into memory as a QByteArray and then the byte array is parsed to produce the Json document. So you get a spike from holding raw text and Json in memory at once. On a PC this doesn't matter, but it matters a lot when memory is constrained. It might be more efficient to QFile::map() the file into memory and then use QByteArray::fromRawData on it. – locka Sep 27 '18 at 13:52
  • It would be awesome if you could post this with an example as an alternative answer @locka – ph_0 Jan 05 '23 at 13:19
2

No need for converting to string and back. With QSettings and QVariant classes you can easily do that. Create QVariant object from QJsonDocument and save it with QSettings. Look at functions QJsonDocument::fromVariant and QJsonDocument::toVariant. Combine them with QSettings class and specifically void QSettings::setValue ( const QString & key, const QVariant & value ) method, that works well with QVariant and that's it.

Also QSettings class has this constructor QSettings::QSettings ( const QString & fileName, Format format, QObject * parent = 0 ) that would allow you to set path to the file - fileName variable

Shf
  • 3,463
  • 2
  • 26
  • 42
  • Please could you explain a little more? How can I use the QSettings to save a QVariant into a file? AFAIK QSettings saves application settings to a determined platform-specific location and not to a file. – Martin Drozdik Jan 21 '14 at 15:27
  • @MartinDrozdik i've edited answer. You can construct QSettings object and open from the location you want. Also QSetting class stores all it's values in QVariant, and that's exactly what we need with QJsonDocument. – Shf Jan 21 '14 at 15:34
  • But `void QSettings::setValue(const QString & key, const QVariant & value )` will save the data into the `.conf` folder or the Windows registry or to a different location over which I have no control. How can I save the `QJsonDocument` to let's say `object.json` in a specific folder? – Martin Drozdik Jan 21 '14 at 15:35
  • @MartinDrozdik yes, there is scecific constructor in QSettings for that purpose, edited answer, http://qt-project.org/doc/qt-4.8/qsettings.html#QSettings-4 . You can set path and format yourself – Shf Jan 21 '14 at 15:37
  • I am sorry, I am not very familiar with QSettings. Can an application have several settings in different locations? Doesn't this break the other settings? – Martin Drozdik Jan 21 '14 at 15:39
  • @MartinDrozdik of course not, it should not break it. Though, you can just use one QSetting file, with different keys. But as long as you create different QSettings objects for different settings files, there really shoud not be any trouble at all – Shf Jan 21 '14 at 15:42
  • @MartinDrozdik the constructor, that i've suggested will just create file, that is not specific for application, you can create and read dozens of them, just treat them like the usual files – Shf Jan 21 '14 at 15:45
  • 3
    This is some convoluted advice. Why go through `QSettings`? The straightforward way is to use `document.toJson()` to get the UTF-8 encoded Json text. – Kuba hasn't forgotten Monica Jan 21 '14 at 16:12
  • @KubaOber and why go through QFile if QSettings is exactly for cases such is this? And IMO `toVariant` and `fromVariant` combine with QSettings way better, then constantly reading and flushing text to files by hands. – Shf Jan 21 '14 at 18:18
  • 1
    @Shf: QSettings will store the json as the string (or binary!) value of a key in the .ini format. That's braindead at best. When reading such a file, QSettings has to parse the value out of it. It just makes no sense at all to use QSettings for this. It sounds to me like you haven't actually used it, and haven't looked at the generated file. – Kuba hasn't forgotten Monica Jan 21 '14 at 18:49
  • @KubaOber let us not assume, what i used and what did not, ok? For a start, why save json in a file in a first place if not to restore data on application relaunch. I don't see another reason, that's why i suggested QSettings, now, what is your reason? In what case you would need to store json in a file and when dances with QFile would be more easier then QSettings? – Shf Jan 21 '14 at 19:17
  • 2
    @Shf: The question is about a json file, not about settings. It's you who assume that it's used to store settings. If one wants to store settings, there's no point to json at all, simply use QSettings directly. Why add another layer of indirection? – Kuba hasn't forgotten Monica Jan 21 '14 at 20:02