© EVILEG 2015-2018
Рекомендует хостинг
TIMEWEB

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

JSON, QJsonArray, QJsonDocument, QJsonObject, QJsonValue, QNetworkAccessManager

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

Итог

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

Видеоурок

Комментарии

Комментарии

Только авторизованные пользователи могут оставлять комментарии.
Пожалуйста, Авторизуйтесь или Зарегистрируйтесь
24 сентября 2018 г. 17:42
edorofeeva

C++ - Тест 001. Первая программа и типы данных

  • Результат 100баллов,
  • Очки рейтинга10
24 сентября 2018 г. 17:37
edorofeeva

C++ - Тест 001. Первая программа и типы данных

  • Результат 66баллов,
  • Очки рейтинга-1
23 сентября 2018 г. 14:38
No Names

C++ - Тест 001. Первая программа и типы данных

  • Результат 60баллов,
  • Очки рейтинга-1
Последние комментарии
24 сентября 2018 г. 15:09
Евгений Легоцкой

Qt Linux - Урок 001. Автозапуск Qt приложения под Linux

А вот здесь у меня есть пример использования supervisor. https://evileg.com/ru/post/3/ Вся статья вам там не интересна, интересен только шаг с настройкой supervisor. Он получается ...
24 сентября 2018 г. 15:00
avovana

Qt Linux - Урок 001. Автозапуск Qt приложения под Linux

Не могли бы дать ссылку на пример? Какое-то рабочее использование. Т.е. у меня есть Qt Gui App, которое я бы хотел запускать при старте системы и в случае, если оно грохнется. Если о чем Вы го...
24 сентября 2018 г. 14:55
Евгений Легоцкой

Qt Linux - Урок 001. Автозапуск Qt приложения под Linux

Если честно, то я не уверен, что это вообще можно реализовать через *.desktop файл. Я сделал предположение на основе того, что вы сказали про *.desktop и рестарт. Все варианты, котор...
24 сентября 2018 г. 14:47
avovana

Qt Linux - Урок 001. Автозапуск Qt приложения под Linux

Просто сейчас правлю сам файл example.desktop. Пытаюсь понять какую пару key=value мне нужно дописать.
24 сентября 2018 г. 14:42
Евгений Легоцкой

Qt Linux - Урок 001. Автозапуск Qt приложения под Linux

Ну я имел ввиду, что дописать в коде вот сюда то, о чём вы говорили про рестарт QString autorunContent("[Desktop Entry]\n" "Type=Application\n" ...
Сейчас обсуждают на форуме
24 сентября 2018 г. 16:47
Евгений_Канусовский@1981

Чтение файлов в python

Добрый вечер Евгений и форумчане! Столкнулся с проблемой чтения файлов в python: файлы с обычным текстом в формате las и txt читаются, например: ~Version information VERS.          ...
24 сентября 2018 г. 13:29
Евгений Легоцкой

Трансляция видео с помощью VLC по RTP

Добрый день! Я не сталкивался, но предположу, что нужно настроить Input Codec в VLC. В настройках есть секция Input Codec, возможно, что там установлено низкое разрешение. ...
21 сентября 2018 г. 8:25
Евгений Легоцкой

Прокси-модель, содержащая на 1 столбец больше, чем модель-источник.

Попробуйте ещё PySide 2 - это официально поддерживаемый пакет привязок Python к Qt, возможно, что там не будет таких проблем.
20 сентября 2018 г. 20:06
Евгений Легоцкой

Qt Installer Framework

Добрый день. Зачем собирать Qt Installer Framework-то из исходников? Я ещё понимаю Qt собирают из исходников статически (хотя тоже считаю по большей части бесполезной тратой времени),...
Присоединяйтесь к нам в социальных сетях