- 1.
- 2. Implementierung
- 1. Widget.h
- 2. Widget.cpp
- 3. Fazit
Betrachten wir ein kleines Beispiel für die Generierung eines JSON-Dokuments beispielsweise aus Text und dem Titel dieses Textes.
Der Text hat zum Beispiel:
- Titel - Erster Titel
- Inhalt - Erster Inhalt
Usw.
Wir fügen diesen Text zu QJsonObject hinzu, das wir dem Array von Texten QJsonArray hinzufügen werden. Das Array von Objekten befindet sich im gemeinsamen Arbeitsverzeichnis QJsonObject , das wir in einer Datei speichern.
Wir werden dies alles über eine grafische Oberfläche tun, die Folgendes hat:
- QLineEdit - titleLineEdit - enthält den Titel des hinzuzufügenden Textes
- QTextEdit - contentTextEdit - enthält den Inhalt des hinzuzufügenden Textes
- QTextEdit - jsonDocumentTextEdit - JSON-Dokumentvorschau
- QPushButton - addButton - Schaltfläche zum Hinzufügen von neuem Text zu JSON
- QPushButton - clearButton - Schaltfläche zum Entfernen aller Texte aus dem aktuellen QJsonObject
- QPushButton - saveButton - Schaltfläche zum Speichern des JSON-Dokuments in einer Datei
- QPushButton - loadButton - Schaltfläche zum Lesen von JSON aus einer Datei
In diesem Fall können wir die JSON-Datei lesen und der gelesenen Datei zusätzliche Texte hinzufügen.
Die Anwendung wird wie folgt aussehen.
Implementierung
Widget.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)); }
Fazit
In diesem speziellen Fall wird QFileDialog verwendet, um den Pfad zu der Datei zu erhalten, die geschrieben wird, und die Datei, die geöffnet wird. Natürlich ist von den Manipulationen mit einer bereits vorhandenen Datei nur das Hinzufügen neuer Texte verfügbar, und Sie können jedes gültige JSON-Dokument öffnen und ihm dann Text hinzufügen. Aber zum Beispiel glaube ich, dass mehr nicht nötig ist.
Скажите пожалуйста, в 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, и уже обращаясь у элементам массива, получвя из него объекты редактировать их