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

РуководствоQtJSON, QJsonArray, QJsonDocument, QJsonObject, QJsonValue, QNetworkAccessManager1761

В процессе написания программы 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();
}

Итог

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

Видеоурок

Реклама

Комментарии

Комментарии

Только авторизованные пользователи могут оставлять комментарии.
Пожалуйста, Авторизуйтесь или Зарегистрируйтесь
Последние комментарии
  • EVILEG
  • 24 апреля 2017 г. 20:44

Подключение вашего Qt приложения к сервисам Google, используя OAuth 2.0

У меня пока мыслей на этот счёт нет ((

Подключение вашего Qt приложения к сервисам Google, используя OAuth 2.0

Пробовал играться с шарком, либо я криво смотрел, либо почему-то POST запросы на oauth.yandex.ru не летят, хотя должны постом лететь, я и исходники QOAuth2AuthorizationCodeFlow ковырял на пред...

  • EVILEG
  • 24 апреля 2017 г. 13:39

Подключение вашего Qt приложения к сервисам Google, используя OAuth 2.0

Возможно, стоит Wireshark`ом запросы посмотреть. В чём отличие идёт аякс запроса от запроса из библиотеки. Возможно, что не хватает какой-нибудь заголовочной информации.

Сейчас обсуждают на форуме
  • Arrow
  • 1 мая 2017 г. 1:00

Callback функции

Первый раз пытаюсь работать с Callback функциями. Помогите понять, что и где я не так делаю. Вот код: ReverseString.h #ifndef REVERSESTRING_H#define REVERSESTRING_H#includ...

  • EVILEG
  • 30 апреля 2017 г. 10:22

QMenu

Вам не кажется, что вы увлеклись со скриншотами? Добавляйте голый программный код в сообщения через специальный диалог. Это кнопка с двумя фигурными скобками. Иногда требуется повторить код у ...

  • CJIaBiK
  • 29 апреля 2017 г. 21:07

QPushButton

Спасибо

  • CJIaBiK
  • 29 апреля 2017 г. 17:57

QWebEngineView

спасибо помогло

  • EVILEG
  • 29 апреля 2017 г. 17:47

Ошибка

Такое случается, когда добавляете новые файлы, а объектный файл, в данном случае mainwindow.obj, не пересобирается как положено. Приходится чистить сборку.