В процессе написания программы EColor появилась задача, в которой было необходимо каким-то образом уведомлять пользователя о том, что вышла новая версия программы. Решением этой задачи стало наличие JSON файла на сайте. С помощью QNetworkAccessManager получаем JSON файл и производим его разбор, благодаря классам библиотеки Qt : QJsonDocument, QJsonObject, QJsonArray. В случае с программой EColor на сайте содержится JSON файл с названием программы, полной версией в строковом варианте и тремя объектами с Мажорной частью версии, Минорной и Патч-версией. При разборе файла производится сравнение текущей версии программы с той, которая находится на сайте. В случае, если на сайте выложена более свежая версия, то программа сообщает об этом пользователю.
Например, по адресу http://www.evileg.ru/it_example.json на сайте располагается JSON файл со следующим содержанием:
{ "departament": "it", "employees": [ {"firstName": "John", "lastName": "Doe"}, {"fisrtName": "Michael", "lastName": "Smith"}, {"firstName": "Anna", "lastName": "Jones"} ], "number" : 3 }
В корневом объекте файла располагается три объекта, второй из которых является массивом. Первый объект - это строковое свойство "departament" , которое содержит название отдела. Второй объект - это массив с именами и фамилиями сотрудников. А третий объект - это число сотрудников типа Integer .
Структура проекта для разбора JSON
- JSONParser.pro - профайл проекта;
- main.cpp - основной файл исходных кодов проекта;
- widget.h - заголовочный файл окна приложения, в котором содержится поле QTextEdit, в которое будет помещен результат парсинга файла;
- widget.cpp - файл исходных кодов с QNetworkAccessManager.
- widget.ui - файл интерфейса программы.
JSONParser.pro
Не забываем подключить в профайле проекта модуль network , чтобы была возможность работать с классом QNetworkAccessManager.
#------------------------------------------------- # # Project created by QtCreator 2016-01-02T13:12:55 # #------------------------------------------------- QT += core gui network greaterThan(QT_MAJOR_VERSION, 4): QT += widgets TARGET = JSONParser TEMPLATE = app SOURCES += main.cpp\ widget.cpp HEADERS += widget.h FORMS += widget.ui
widget.h
Подключаем класс QNetworkAccessManager , также в заголовочном файле объявлен СЛОТ onResult(QNetworkReply *reply) , в котором будет разбираться JSON файл при получении ответа от сайта с содержимым файла.
#ifndef WIDGET_H #define WIDGET_H #include <QWidget> #include <QNetworkAccessManager> namespace Ui { class Widget; } class Widget : public QWidget { Q_OBJECT public: explicit Widget(QWidget *parent = 0); ~Widget(); private slots: // Обработчик данных полученных от объекта QNetworkAccessManager void onResult(QNetworkReply *reply); private: Ui::Widget *ui; QNetworkAccessManager *networkManager; }; #endif // WIDGET_H
widget.cpp
Процесс заключается в том, чтобы создать объект QJsonDocument и записать в него содержимое ответа QNetworkReply. После чего забираем из документа корневой объект root , который будет содержать все три свойства. После этого забираем по названиям свойств их значения. Из второго свойства "employes" забираем массив с именами и фамилиями сотрудников отдела. Все данные помещаем в поле ui->textEdit.
#include "widget.h" #include "ui_widget.h" #include <QJsonDocument> #include <QJsonObject> #include <QJsonArray> #include <QUrlQuery> #include <QNetworkReply> #include <QUrl> Widget::Widget(QWidget *parent) : QWidget(parent), ui(new Ui::Widget) { ui->setupUi(this); networkManager = new QNetworkAccessManager(); // Подключаем networkManager к обработчику ответа connect(networkManager, &QNetworkAccessManager::finished, this, &Widget::onResult); // Получаем данные, а именно JSON файл с сайта по определённому url networkManager->get(QNetworkRequest(QUrl("http://www.evileg.ru/it_example.json"))); } Widget::~Widget() { delete ui; } void Widget::onResult(QNetworkReply *reply) { // Если ошибки отсутсвуют if(!reply->error()){ // То создаём объект Json Document, считав в него все данные из ответа QJsonDocument document = QJsonDocument::fromJson(reply->readAll()); // Забираем из документа корневой объект QJsonObject root = document.object(); /* Находим объект "departament", который располагается самым первым в корневом объекте. * С помощью метода keys() получаем список всех объектов и по первому индексу * забираем название объекта, по которому получим его значение * */ ui->textEdit->append(root.keys().at(0) + ": " + root.value(root.keys().at(0)).toString()); // Второе значение пропишем строкой QJsonValue jv = root.value("employees"); // Если значение является массивом, ... if(jv.isArray()){ // ... то забираем массив из данного свойства QJsonArray ja = jv.toArray(); // Перебирая все элементы массива ... for(int i = 0; i < ja.count(); i++){ QJsonObject subtree = ja.at(i).toObject(); // Забираем значения свойств имени и фамилии добавляя их в textEdit ui->textEdit->append(subtree.value("firstName").toString() + " " + subtree.value("lastName").toString()); } } // В конце забираем свойство количества сотрудников отдела и также выводим в textEdit ui->textEdit->append(QString::number(root.value("number").toInt())); } reply->deleteLater(); }
Итог
В результате работы данного программного кода получится следующий результат, который показан на ниже следующем изображении. Также работу приложения Вы можете увидеть на в видеоуроке.