Реклама

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

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

В процессе написания программы 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
  • 13 июля 2017 г. 2:12

Qt/C++ - Урок 023. Перетаскивание QGraphicsItem на QGraphicsScene мышью

Ну например так можете сделать.void MoveItem::mousePressEvent(QGraphicsSceneMouseEvent *event){ if (QApplication::mouseButtons() == Qt::RightButton) { this->deleteLa...

  • Mark
  • 13 июля 2017 г. 1:26

Qt/C++ - Урок 023. Перетаскивание QGraphicsItem на QGraphicsScene мышью

Подскажите пожалуйста как в данном проекте по перетаскиванию организовать удаление объекта со scene методом delete item, допустим при щелчке ПКМ по объекту QGraphicsScene. Мои попытки оказалис...

  • EVILEG
  • 10 июля 2017 г. 21:34

Qt/C++ - Урок 048. QThread - работа с потоками с помощью moveToThread

А что делали? Повторяете урок или как? Пытались просто скачать проект в конце статьи и запустить?

Qt/C++ - Урок 048. QThread - работа с потоками с помощью moveToThread

У меня происходит переполнение счетчика count, появляется ошибка malloc(): memory corruption (fast). Не подскажите, как с этим бороться?

  • EVILEG
  • 9 июля 2017 г. 2:07

GameDev на Qt - Урок 3. Уничтожение противников

Поэтому в пятом уроке есть исходники всего проекта )))). Вообще, все эти материалы были не предыдущей версии сайта, которая на WordPress. Во время переноса мог что-то потерять.

Сейчас обсуждают на форуме

Как реализовать отправку e-mail

Возможно что уже и нет необходимости в почтовом клиенте, но в своё время так же столкнулся с данной проблемой в QT. Нашел один интересный проект под названием libqxt, там реализовано дов...

  • BlinCT
  • 18 июля 2017 г. 0:00

тестирование классов в QT

Это был вопрос или утверждение? Не понятно что вы хотели этим сказать. Интересное у вас обращение.

  • Asteri
  • 14 июля 2017 г. 12:23

css

Делюсь, может, пригодится когда-нибудь) QTableView QHeaderView { background-color: #ffffff; } Вот так эта проблема лечится, градиент задать не получается, но хоть...

  • EVILEG
  • 12 июля 2017 г. 19:52

QSqlQuery выполнение sql запросов из файла

Мне думается, что это уже будет дело вкуса и вашего взгляда на проект. Если Вы действительно собираетесь просто скармливать своему софту SQL скрипты, которые должны будут выполняться для...

QML Canvas + Line. Bug?

Вот оно что, значит не баг) Спасибо