
Привет, хабр!
На хабре еще не писали про QJson — отличный и очень простой инструмент для работы с JSON на Qt. Вообще Qt рекоммендуют использовать XML — но мне кажется что в очень многих случаях он бывает чересчур уж избыточным или лишним. В некоторых случаях лучше использовать JSON. В этой заметке я расскажу как скачать, собрать и использовать QJson для работы с JSON в Qt.
Внимание! Этот пост — заметка. Все что вы тут прочитаете можно найти в гугле и на офф сайте проекта — но я думаю что такая заметка не будет лишней.
Получение
QJson — 3rd party, для того чтобы с ним работать, его нужно сначала получить и собрать. Это можно сделать двумя путями — с оффициального сайта проекта или с gitorious. Качаем, распаковываем и переходим к следующему этапу.
Установка
Разработчики QJson рекомендуют собирать через cmake.
Windows
set PATH=%PATH%;C:\path_to_cmake_\bin cd path_where_i_unpacked_qjson cd build cmake -G "MinGW Makefiles" .. mingw32-make mingw32-make install
Linux/Mac
cd where_i_downloaded_qjson mkdir build cd build cmake .. make sudo make install
Начинаем работу
QJson позволяет работать с JSON на основе QVariant (QVariantMap, QVariantList) что дает ему гибкость. Он умеет парсить, писать JSON и сиреализировать QObject'ы.
Для начала — добавим в .pro файл строчку:
LIBS += -lqjson
Теперь наш проект зависит от qjson и умеет работать с ним.
Парсим QJson
#include<qjson/parser.h> QVariant parseJSON(const QString &json) { QJson::Parser parser; // парсер для json'а bool ok; // false если будут ошибки return parser.parse (json, &ok); // QVariant }
Пусть мы будем парсить этот JSON:
{ "encoding" : "UTF-8", "plug-ins" : [ "python", "c++", "ruby" ], "indent" : { "length" : 3, "use_space" : true } }
Вот этим кодом:
QJson::Parser parser; bool ok; QVariantMap result = parser.parse (json, &ok).toMap(); if (!ok) { qFatal("Пока парсили возникла ошибочка - беда-то."); exit (1); } qDebug() << "encoding:" << result["encoding"].toString(); qDebug() << "plugins:"; foreach (QVariant plugin, result["plug-ins"].toList()) { qDebug() << "\t-" << plugin.toString(); } QVariantMap nestedMap = result["indent"].toMap(); qDebug() << "length:" << nestedMap["length"].toInt(); qDebug() << "use_space:" << nestedMap["use_space"].toBool();
Вывод в debug-консоль будет такой:
encoding: "UTF-8" plugins: - "python" - "c++" - "ruby" length: 3 use_space: true
Пишем из QVariant в JSON
Я только оставлю сдесь этот пример:
QVariantList people; QVariantMap bob; bob.insert("Name", "Bob"); bob.insert("Phonenumber", 123); QVariantMap alice; alice.insert("Name", "Alice"); alice.insert("Phonenumber", 321); people << bob << alice; QJson::Serializer serializer; QByteArray json = serializer.serialize(people); qDebug() << json;
Вывод в debug-консоли будет таким:
"[ { "Name" : "Bob", "Phonenumber" : 123 }, { "Name" : "Alice", "Phonenumber" : 321 } ]"
Замечательно, не так-ли?
Сериализация QObject
Также возможнa сериализация экземпляра QObject в JSON. Все атрибуты класса определяется как свойства и будут упорядочены. Предположим, что определение класса выглядит следующим образом:
class Person : public QObject { Q_OBJECT Q_PROPERTY(QString name READ name WRITE setName) Q_PROPERTY(int phoneNumber READ phoneNumber WRITE setPhoneNumber) Q_PROPERTY(Gender gender READ gender WRITE setGender) Q_PROPERTY(QDate dob READ dob WRITE setDob) Q_ENUMS(Gender) public: Person(QObject* parent = 0); ~Person(); QString name() const; void setName(const QString& name); int phoneNumber() const; void setPhoneNumber(const int phoneNumber); enum Gender {Male, Female}; void setGender(Gender gender); Gender gender() const; QDate dob() const; void setDob(const QDate& dob); private: QString m_name; int m_phoneNumber; Gender m_gender; QDate m_dob; };
Вот этот код превратит объект Person в JSON:
Person person; person.setName("Flavio"); person.setPhoneNumber(123456); person.setGender(Person::Male); person.setDob(QDate(1982, 7, 12)); QVariantMap variant = QObjectHelper::qobject2qvariant(&person); Serializer serializer; qDebug() << serializer.serialize( variant);
В консоли будет следующий вывод:
{ "dob" : "1982-07-12", "gender" : 0, "name" : "Flavio", "phoneNumber" : 123456 }
Также возможно парсить JSON в QObject. Представим, что вышеуказанный JSON есть в каком-то QString.
Parser parser; QVariant variant = parser.parse(json); // json - наш JSON в QString Person person; QObjectHelper::qvariant2qobject(variant.toMap(), &person); // запишет в person пропертис из json
Полное API
Отлично описано на английском языке тут.
Мой комментарий
Кому это может быть полезно? Да кому угодно! Любому разработчику которому надо хранить информацию в легком или user-friendly формате.
Спасибо за внимание.
