В процессе написания программы 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();
- }
Итог
В результате работы данного программного кода получится следующий результат, который показан на ниже следующем изображении. Также работу приложения Вы можете увидеть на в видеоуроке.