- 1.
- 2. Іске асыру
- 1. виджет.h
- 2. widget.cpp
- 3. Қорытынды
Мысалы, мәтіннен және осы мәтіннің тақырыбынан JSON құжатын жасаудың шағын мысалын қарастырайық.
Мысалы, мәтінде:
- Атауы - Бірінші атауы
- Мазмұн - Бірінші мазмұн
Және т.б.
Біз бұл мәтінді QJsonObject ішіне қосамыз, оны біз QJsonArray мәтіндер массивіне қосамыз. Нысандардың массиві файлға сақтайтын жалпы жұмыс істейтін QJsonObject ішінде болады.
Мұның бәрін біз графикалық интерфейс арқылы жасаймыз, ол:
- QLineEdit - titleLineEdit - қосылатын мәтіннің тақырыбын қамтиды
- QTextEdit - contentTextEdit - қосылатын мәтіннің мазмұнын қамтиды
- QTextEdit - jsonDocumentTextEdit - JSON құжатын алдын ала қарау
- QPushButton - addButton - JSON файлына жаңа мәтін қосу түймесі
- QPushButton - clearButton - ағымдағы QJsonObject ішінен барлық мәтіндерді жою түймесі
- QPushButton - saveButton - JSON құжатын файлға сақтау түймесі
- QPushButton - loadButton - файлдан JSON оқуға арналған түйме
Бұл жағдайда біз JSON файлын оқи аламыз және оқылатын файлға қосымша мәтіндерді қоса аламыз.
Қолданба келесідей болады.
Іске асыру
виджет.h
#ifndef WIDGET_H #define WIDGET_H #include <QWidget> #include <QJsonObject> namespace Ui { class Widget; } class Widget : public QWidget { Q_OBJECT public: explicit Widget(QWidget *parent = nullptr); ~Widget(); private: // Слот добавления нового текста в массив текстов void onAddButtonClicked(); // Слот удаления всей информации о текстах в текущем объекте void onClearButtonClicked(); // Слот сохранения текстов в json файл void onSaveButtonClicked(); // Слот загрузки текстов в программу из json файла void onLoadButtonClicked(); Ui::Widget *ui; // Текущий json объект, с которым производится работа QJsonObject m_currentJsonObject; }; #endif // WIDGET_H
widget.cpp
#include "widget.h" #include "ui_widget.h" #include <QFileDialog> #include <QFile> #include <QDir> #include <QJsonObject> #include <QJsonArray> #include <QJsonDocument> Widget::Widget(QWidget *parent) : QWidget(parent), ui(new Ui::Widget) { ui->setupUi(this); // Подключение слотов обработчиков к сигналам клика по кнопкам connect(ui->addButton, &QPushButton::clicked, this, &Widget::onAddButtonClicked); connect(ui->clearButton, &QPushButton::clicked, this, &Widget::onClearButtonClicked); connect(ui->saveButton, &QPushButton::clicked, this, &Widget::onSaveButtonClicked); connect(ui->loadButton, &QPushButton::clicked, this, &Widget::onLoadButtonClicked); } Widget::~Widget() { delete ui; } void Widget::onAddButtonClicked() { // Создаём объект текста QJsonObject textObject; textObject["title"] = ui->titleLineEdit->text(); // Устанавливаем заголовок текста textObject["content"] = ui->contentTextEdit->toPlainText(); // Устанавливаем содержание текста QJsonArray textsArray = m_currentJsonObject["texts"].toArray(); // Забираем текущий массив текстов, даже если он не существует, он будет создан автоматически textsArray.append(textObject); // Добавляем объект текста в массив m_currentJsonObject["texts"] = textsArray; // Сохраняем массив обратно в текущий объект // Устанавливаем текст всего Json объекта в текстовое поле для проверки ui->jsonDocumentTextEdit->setText(QJsonDocument(m_currentJsonObject).toJson(QJsonDocument::Indented)); } void Widget::onClearButtonClicked() { m_currentJsonObject = QJsonObject(); // Пересоздаём новый текущий QJsonObject ui->jsonDocumentTextEdit->clear(); // Очищаем текстовое поле // Устанавливаем текст всего Json объекта в текстовое поле, чтобы увидеть, что это пустой объект. // Увидите следующее -> {} ui->jsonDocumentTextEdit->setText(QJsonDocument(m_currentJsonObject).toJson(QJsonDocument::Indented)); } void Widget::onSaveButtonClicked() { // С помощью диалогового окна получаем имя файла с абсолютным путём QString saveFileName = QFileDialog::getSaveFileName(this, tr("Save Json File"), QString(), tr("JSON (*.json)")); QFileInfo fileInfo(saveFileName); // С помощью QFileInfo QDir::setCurrent(fileInfo.path()); // установим текущую рабочую директорию, где будет файл, иначе может не заработать // Создаём объект файла и открываем его на запись QFile jsonFile(saveFileName); if (!jsonFile.open(QIODevice::WriteOnly)) { return; } // Записываем текущий объект Json в файл jsonFile.write(QJsonDocument(m_currentJsonObject).toJson(QJsonDocument::Indented)); jsonFile.close(); // Закрываем файл } void Widget::onLoadButtonClicked() { // Выбираем файл QString openFileName = QFileDialog::getOpenFileName(this, tr("Open Json File"), QString(), tr("JSON (*.json)")); QFileInfo fileInfo(openFileName); // С помощью QFileInfo QDir::setCurrent(fileInfo.path()); // установим текущую рабочую директорию, где будет файл // Создаём объект файла и открываем его на чтение QFile jsonFile(openFileName); if (!jsonFile.open(QIODevice::ReadOnly)) { return; } // Считываем весь файл QByteArray saveData = jsonFile.readAll(); // Создаём QJsonDocument QJsonDocument jsonDocument(QJsonDocument::fromJson(saveData)); // Из которого выделяем объект в текущий рабочий QJsonObject m_currentJsonObject = jsonDocument.object(); // Очищаем текстовое поле ui->jsonDocumentTextEdit->clear(); // И устанавливаем в проверочное текстовое поле содержимое Json объекта ui->jsonDocumentTextEdit->setText(QJsonDocument(m_currentJsonObject).toJson(QJsonDocument::Indented)); }
Қорытынды
Бұл нақты жағдайда QFileDialog жазылатын файлға және ашылатын файлға жолды алу үшін пайдаланылады. Әрине, бар файлмен манипуляциялардан тек жаңа мәтіндерді қосуға болады және кез келген жарамды JSON құжатын ашып, оған мәтін қосуға болады. Бірақ, мысалы, мен көп нәрсе қажет емес деп есептеймін.
Скажите пожалуйста, в 55 строке получаем saveFileNam, это видимо полное имя файла. Но где потом сообщается полный путь файлу json при его записи?
В saveFileName будет полный путь к файлу с его именем. В диалоге просто вводите имя файла с расширением, а QFileDialog возвращает имя файла и полный путь к нему.
Можете увидеть это, если добавите вывод в qDebug
А через fileInfo я выдернул путь к файлу, чтобы установить рабочую директорию через QDir::setCurrent();, чтобы указать, где именно сохраняется файл. А когда я передаю saveFileName в QFile, даже с наличием пути в имени, всё будет нормально работать, путь должен быть отброшен автоматически.
Спасибо.
Скажите пожалуйста, зачем 65 строка? написал по образцу часть кода, выдало ошибку D:\QTProject\ReaderResume\main.cpp:58: ошибка: return-statement with no value, in function returning 'int' [-fpermissive]
return;
^
Без return работает
зачем вы слот написали с возвращаемым значением int?
У вас сигнатура в вашем коде так написана
слоту обычно не требуется возвращаемое значение.
return прерывает выполнение метода, чтобы не шло дальше, если файл не открылся в данном случае.
Спасибо
Скажите пожалуйста, как добавить в массив QJsonArray другой массив QVector<QString> TextArra?
Как я понял, это можно сделать в цикле поочередно для каждого члена массива, но можно ли сразу перевести одной командой?
Думаю, что через алгоритмические методы вставки из стандартной библиотеки и использование итераторов с лямбда функциями можно написать и в одну строку.
Но судя по вашим вопросам, могу сказать, что вы не знакомы со всем этим зоопарком, поэтому пока не забивайте себе этим голову, в процессе работы сами прийдёте к использованию данного функционала. Так что сделайте через цикл поочерёдно. Просто напишите
Также вы можете сами написать эту вспомогательную команду.
Спасибо. И скажите пожалуйста, как перевести QString в QJsonValue
QJsonValue::fromVariant(const QVariant& variant);
Спасибо.
Скажите пожалуйста, в json файле размещен массив, в этот массив нужно добавить еще один элемент массива. Но считывать весь массив - тратить дополнительное время. Можно ли, при условии, что я знаю, что там только один массив, как то быстро добавить один элемент?
Возможно, через итератор можно будет сделать. Я не проверял. сам по себе метод toArray() возвращает копию массива...
На первый взгляд я не увидел необходимой возможности, хотя подумал об этом.
Возможно с итераторами через метод find, можно будет взять массив и уже в нём покопаться. Но не факт.
А можно сразу перейти в конец документа, если нет ], то записывать с начала, а если есть ] , то ставить запятую и дописывать еще один элемент?
Это уже вручную нужно реализовывать. Только это не нужно, пока действительно не будет проблемы по производительности.
А вообще, если нужно хранение данных, то возможно и насчёт базы данных стоит подумать. Хотя бы SQLite можно использовать. Это будет эффективнее.
Как отредактировать данные?
Смотря что хотите и в каком виде эти данные. Если в текстовом, то их нужно прочитать, перевести в QJsonDocument, из него достать массив connect, и уже обращаясь у элементам массива, получвя из него объекты редактировать их