Evgenii Legotckoi
2 января 2016 г. 21:33

Qt/C++ - Урок 041. JSON файл - получаем с сайта и производим его разбор

В процессе написания программы EColor появилась задача, в которой было необходимо каким-то образом уведомлять пользователя о том, что вышла новая версия программы. Решением этой задачи стало наличие JSON файла на сайте. С помощью QNetworkAccessManager получаем JSON файл и производим его разбор, благодаря классам библиотеки Qt : QJsonDocument, QJsonObject, QJsonArray. В случае с программой EColor на сайте содержится JSON файл с названием программы, полной версией в строковом варианте и тремя объектами с Мажорной частью версии, Минорной и Патч-версией. При разборе файла производится сравнение текущей версии программы с той, которая находится на сайте. В случае, если на сайте выложена более свежая версия, то программа сообщает об этом пользователю.


Например, по адресу http://www.evileg.ru/it_example.json на сайте располагается JSON файл со следующим содержанием:

  1. {
  2. "departament": "it",
  3. "employees": [
  4. {"firstName": "John", "lastName": "Doe"},
  5. {"fisrtName": "Michael", "lastName": "Smith"},
  6. {"firstName": "Anna", "lastName": "Jones"}
  7. ],
  8. "number" : 3
  9. }

В корневом объекте файла располагается три объекта, второй из которых является массивом. Первый объект - это строковое свойство "departament" , которое содержит название отдела. Второй объект - это массив с именами и фамилиями сотрудников. А третий объект - это число сотрудников типа Integer .

Структура проекта для разбора JSON

  • JSONParser.pro - профайл проекта;
  • main.cpp - основной файл исходных кодов проекта;
  • widget.h - заголовочный файл окна приложения, в котором содержится поле QTextEdit, в которое будет помещен результат парсинга файла;
  • widget.cpp - файл исходных кодов с QNetworkAccessManager.
  • widget.ui - файл интерфейса программы.

JSONParser.pro

Не забываем подключить в профайле проекта модуль network , чтобы была возможность работать с классом QNetworkAccessManager.

  1. #-------------------------------------------------
  2. #
  3. # Project created by QtCreator 2016-01-02T13:12:55
  4. #
  5. #-------------------------------------------------
  6.  
  7. QT += core gui network
  8.  
  9. greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
  10.  
  11. TARGET = JSONParser
  12. TEMPLATE = app
  13.  
  14.  
  15. SOURCES += main.cpp\
  16. widget.cpp
  17.  
  18. HEADERS += widget.h
  19.  
  20. FORMS += widget.ui

widget.h

Подключаем класс QNetworkAccessManager , также в заголовочном файле объявлен СЛОТ onResult(QNetworkReply *reply) , в котором будет разбираться JSON файл при получении ответа от сайта с содержимым файла.

  1. #ifndef WIDGET_H
  2. #define WIDGET_H
  3.  
  4. #include <QWidget>
  5. #include <QNetworkAccessManager>
  6.  
  7. namespace Ui {
  8. class Widget;
  9. }
  10.  
  11. class Widget : public QWidget
  12. {
  13. Q_OBJECT
  14.  
  15. public:
  16. explicit Widget(QWidget *parent = 0);
  17. ~Widget();
  18.  
  19. private slots:
  20. // Обработчик данных полученных от объекта QNetworkAccessManager
  21. void onResult(QNetworkReply *reply);
  22.  
  23. private:
  24. Ui::Widget *ui;
  25. QNetworkAccessManager *networkManager;
  26. };
  27.  
  28. #endif // WIDGET_H

widget.cpp

Процесс заключается в том, чтобы создать объект QJsonDocument и записать в него содержимое ответа QNetworkReply. После чего забираем из документа корневой объект root , который будет содержать все три свойства. После этого забираем по названиям свойств их значения. Из второго свойства "employes" забираем массив  с именами и фамилиями сотрудников отдела. Все данные помещаем в поле ui->textEdit.

  1. #include "widget.h"
  2. #include "ui_widget.h"
  3.  
  4. #include <QJsonDocument>
  5. #include <QJsonObject>
  6. #include <QJsonArray>
  7. #include <QUrlQuery>
  8. #include <QNetworkReply>
  9. #include <QUrl>
  10.  
  11. Widget::Widget(QWidget *parent) :
  12. QWidget(parent),
  13. ui(new Ui::Widget)
  14. {
  15. ui->setupUi(this);
  16.  
  17. networkManager = new QNetworkAccessManager();
  18. // Подключаем networkManager к обработчику ответа
  19. connect(networkManager, &QNetworkAccessManager::finished, this, &Widget::onResult);
  20. // Получаем данные, а именно JSON файл с сайта по определённому url
  21. networkManager->get(QNetworkRequest(QUrl("http://www.evileg.ru/it_example.json")));
  22. }
  23.  
  24. Widget::~Widget()
  25. {
  26. delete ui;
  27. }
  28.  
  29. void Widget::onResult(QNetworkReply *reply)
  30. {
  31. // Если ошибки отсутсвуют
  32. if(!reply->error()){
  33.  
  34. // То создаём объект Json Document, считав в него все данные из ответа
  35. QJsonDocument document = QJsonDocument::fromJson(reply->readAll());
  36.  
  37. // Забираем из документа корневой объект
  38. QJsonObject root = document.object();
  39. /* Находим объект "departament", который располагается самым первым в корневом объекте.
  40. * С помощью метода keys() получаем список всех объектов и по первому индексу
  41. * забираем название объекта, по которому получим его значение
  42. * */
  43. ui->textEdit->append(root.keys().at(0) + ": " + root.value(root.keys().at(0)).toString());
  44.  
  45. // Второе значение пропишем строкой
  46. QJsonValue jv = root.value("employees");
  47. // Если значение является массивом, ...
  48. if(jv.isArray()){
  49. // ... то забираем массив из данного свойства
  50. QJsonArray ja = jv.toArray();
  51. // Перебирая все элементы массива ...
  52. for(int i = 0; i < ja.count(); i++){
  53. QJsonObject subtree = ja.at(i).toObject();
  54. // Забираем значения свойств имени и фамилии добавляя их в textEdit
  55. ui->textEdit->append(subtree.value("firstName").toString() +
  56. " " +
  57. subtree.value("lastName").toString());
  58. }
  59. }
  60. // В конце забираем свойство количества сотрудников отдела и также выводим в textEdit
  61. ui->textEdit->append(QString::number(root.value("number").toInt()));
  62. }
  63. reply->deleteLater();
  64. }

Итог

В результате работы данного программного кода получится следующий результат, который показан на ниже следующем изображении. Также работу приложения Вы можете увидеть на в видеоуроке.

Видеоурок

Вам это нравится? Поделитесь в социальных сетях!

Комментарии

Только авторизованные пользователи могут публиковать комментарии.
Пожалуйста, авторизуйтесь или зарегистрируйтесь