Evgenii Legotckoi
Evgenii Legotckoi28. August 2015 09:34

Qt/C++ - Lektion 011. XML-Dateien in Qt – Lesen und Schreiben

Qt-Entwicklungstools enthalten Funktionen zum Arbeiten mit XML -Dateien, mit denen Sie sowohl XML -Dateien erstellen als auch lesen können, was beim Erstellen von Programmen zum automatischen Erstellen von XML -Markups und -Konfigurationen nützlich sein kann Dateien mit XML oder zum Parsen von XML-Dateien .

Klasse QXmlStreamWriter wird verwendet, um XML-Dateien zu schreiben, während eine andere Klasse QXmlStreamReader zum Lesen von XML-Dateien verwendet wird.

Der Programmcode wurde in QtCreator 3.3.1 basierend auf Qt 5.4.1 geschrieben.

Projektstruktur für die Arbeit mit XML-Datei

Dieses Projekt verwendet ein Minimum an Dateien:

  • XMLExample.pro - Profil;
  • mainwindow.h - Header-Datei des Hauptanwendungsfensters;
  • mainwindow.cpp - Fensterquellcode;
  • main.cpp - die Hauptquelldatei, von der aus die Anwendung startet;
  • mainwindow.ui - Form des Hauptanwendungsfensters;

mainwindow.ui

Diesmal müssen Sie dem Formular des Hauptfensters eine ausreichend große Anzahl von Elementen hinzufügen, damit es wie folgt aussieht:

Hauptanwendungsfenster für die Arbeit mit XML-Datei Liste aller Elemente, die für die Arbeit im Programmcode verwendet werden:

  • checkBox - erste Checkbox;
  • checkBox_1 - zweites Kontrollkästchen;
  • checkBox_2 - die dritte Checkbox;
  • lineEditCB1 - lineEdit für das erste Kontrollkästchen;
  • lineEditCB2 - lineEdit für das zweite Kontrollkästchen;
  • lineEditCB3 - lineEdit für das dritte Kontrollkästchen;
  • lineEditRead - lineEdit, das den Pfad zu der zu lesenden Datei angibt;
  • lineEditWrite - lineEdit, das den Pfad zu der zu schreibenden Datei angibt;
  • dialogReadButton - eine Schaltfläche zum Aufrufen des Dateispeicherdialogs, in diesem Fall wird einfach eine Datei zum Bearbeiten ausgewählt;
  • dialogButton - eine Schaltfläche zum Aufrufen des Dateiaufzeichnungsdialogs, in diesem Fall einfach eine Datei auswählen, mit der auch gearbeitet wird;
  • readButton - Schaltfläche zum Lesen aus einer Datei;
  • generateButton - eine Schaltfläche zum Schreiben in eine Datei.

mainwindow.h

Die Header-Datei enthält Bibliotheken zum Arbeiten mit QXmlStreamWriter und QXmlStreamReader Außerdem werden Slots für Schaltflächenklicks deklariert.

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QFileDialog>
#include <QXmlStreamWriter>
#include <QXmlStreamReader>
#include <QXmlStreamAttribute>
#include <QMessageBox>
#include <QFile>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

private slots:
    /* Слоты обработчиков кнопок, работающих с записью в файл */
    void on_generateButton_clicked();
    void on_dialogButton_clicked();

    /* Слоты обработчиков кнопок, работающих с чтением из файла */
    void on_readButton_clicked();
    void on_dialogReadButton_clicked();

private:
    Ui::MainWindow *ui;
};

#endif // MAINWINDOW_H

mainwindow.cpp

Diese Quelldatei liest und schreibt Daten in eine XML-Datei sowie die Substitution von Parametern aus der XML-Datei in die Formulare des Hauptfensters.

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
}

MainWindow::~MainWindow()
{
    delete ui;
}

/* Метод, выполняющий запись информации в XML-файл
 * */
void MainWindow::on_generateButton_clicked()
{
    /* Открываем файл для Записи с помощью пути, указанного в lineEditWrite */
    QFile file(ui->lineEditWrite->text());
    file.open(QIODevice::WriteOnly);

    /* Создаем объект, с помощью которого осуществляется запись в файл */
    QXmlStreamWriter xmlWriter(&file);
    xmlWriter.setAutoFormatting(true);  // Устанавливаем автоформатирование текста
    xmlWriter.writeStartDocument();     // Запускаем запись в документ
    xmlWriter.writeStartElement("resources");   // Записываем первый элемент с его именем

    xmlWriter.writeStartElement("checkBox_1");  // Записываем тег с именем для первого чекбокса
    /* На основе состояния чекбокса записываем атрибут "boolean"
     * с указанием состояния чекбокса в этом атрибуте
     * */
    xmlWriter.writeAttribute("boolean",
                             (ui->checkBox->isChecked() ? "true" : "false"));
    /* Записываем также в тело этого элемента строку из соответствующего lineEdit
     * */
    xmlWriter.writeCharacters(ui->lineEditCB1->text());
    xmlWriter.writeEndElement();        // Закрываем тег


    /* Повторяем те же действия для двух других чекбоксов
     * */
    xmlWriter.writeStartElement("checkBox_2");
    xmlWriter.writeAttribute("boolean",
                             (ui->checkBox_2->isChecked() ? "true" : "false"));
    xmlWriter.writeCharacters(ui->lineEditCB2->text());
    xmlWriter.writeEndElement();

    xmlWriter.writeStartElement("checkBox_3");
    xmlWriter.writeAttribute("boolean",
                             (ui->checkBox_3->isChecked() ? "true" : "false"));
    xmlWriter.writeCharacters(ui->lineEditCB3->text());
    xmlWriter.writeEndElement();

    /* Закрываем тег "resources"
     * */
    xmlWriter.writeEndElement();
    /* Завершаем запись в документ
     * */
    xmlWriter.writeEndDocument();
    file.close();   // Закрываем файл
}

/* Метод, вызывающий диалоговое окно выбора файла для сохранения данных
 * */
void MainWindow::on_dialogButton_clicked()
{
    /* Вызываем диалог выбора файла для сохранения */
    QString filename = QFileDialog::getSaveFileName(this,
                                           tr("Save Xml"), ".",
                                           tr("Xml files (*.xml)"));
    /* Устанавливаем в lineEditWrite путь к файлу, с которым будем работать */
    if(filename != ""){
        ui->lineEditWrite->setText(filename);
    }
}

void MainWindow::on_readButton_clicked()
{
    /* Открываем файл для Чтения с помощью пути, указанного в lineEditWrite */
    QFile file(ui->lineEditRead->text());
    if (!file.open(QFile::ReadOnly | QFile::Text))
    {
        QMessageBox::warning(this,
                             "Ошибка файла",
                             "Не удалось открыть файл",
                             QMessageBox::Ok);
    } else {
        /* Создаем объект, с помощью которого осуществляется чтение из файла */
        QXmlStreamReader xmlReader;
        xmlReader.setDevice(&file);
        xmlReader.readNext();   // Переходит к первому элементу в файле

        /* Крутимся в цикле до тех пор, пока не достигнем конца документа
         * */
        while(!xmlReader.atEnd())
        {
            /* Проверяем, является ли элемент началом тега
             * */
            if(xmlReader.isStartElement())
            {
                /* Проверяем, относится ли тег к одному из чекбоксов.
                 * Если "ДА", то выполняем проверку атрибута чекбокса
                 * и записи для lineEdit
                 * */
                if(xmlReader.name() == "checkBox_1")
                {
                    /* Забираем все атрибуты тега и перебираем их для проверки на соответствие
                     * нужному нам атрибуту
                     * */
                    foreach(const QXmlStreamAttribute &attr, xmlReader.attributes()) {
                        /* Если найден нужный атрибут, то по его значению устанавливаем
                         * состояние чекбокса
                         * */
                        if (attr.name().toString() == "boolean") {
                            QString attribute_value = attr.value().toString();
                            ui->checkBox->setChecked((QString::compare(attribute_value , "true") == 0) ? true : false);

                        }
                    }
                    /* забираем текст из тела тега и вставляем его соответствующий lineEdit
                     * */
                    ui->lineEditCB1->setText(xmlReader.readElementText());

                    /* аналогично работаем с остальными тегами */
                } else if (xmlReader.name() == "checkBox_2"){
                    foreach(const QXmlStreamAttribute &attr, xmlReader.attributes()) {
                        if (attr.name().toString() == "boolean") {
                            QString attribute_value = attr.value().toString();
                            ui->checkBox_2->setChecked((QString::compare(attribute_value , "true") == 0) ? true : false);

                        }
                    }
                    ui->lineEditCB2->setText(xmlReader.readElementText());
                } else if (xmlReader.name() == "checkBox_3"){
                    foreach(const QXmlStreamAttribute &attr, xmlReader.attributes()) {
                        if (attr.name().toString() == "boolean") {
                            QString attribute_value = attr.value().toString();
                            ui->checkBox_3->setChecked((QString::compare(attribute_value , "true") == 0) ? true : false);

                        }
                    }
                    ui->lineEditCB3->setText(xmlReader.readElementText());
                }
            }
            xmlReader.readNext(); // Переходим к следующему элементу файла
        }
        file.close(); // Закрываем файл

        /* В данном коде не осуществляется проверка на закрытие тега
         * поскольку в этом нет необходимости, но функционал QXmlStreamReader это позволяет
         * */
    }
}

/* Метод, вызывающий диалоговое окно выбора файла для чтения данных
 * */
void MainWindow::on_dialogReadButton_clicked()
{
    /* Вызываем диалог выбора файла для чтения */
    QString filename = QFileDialog::getOpenFileName(this,
                                       tr("Open Xml"), ".",
                                       tr("Xml files (*.xml)"));
   /* Устанавливаем в lineEditRead путь к файлу, с которым будем работать */
    if(filename != ""){
        ui->lineEditRead->setText(filename);
    }
}

Als Ergebnis erhalten wir die Möglichkeit, eine XML-Datei mit Parametern Checkboxen und unseren Objekten vom Typ lineEdit zu erstellen, sowie diese Datei zu parsen und die empfangenen Daten in die entsprechenden Kontrollkästchen und Objekte lineEdit

Die resultierende Datei sollte wie folgt aussehen:

<?xml version="1.0" encoding="UTF-8"?>
<resources>
    <checkBox_1 boolean="false">XML</checkBox_1>
    <checkBox_2 boolean="false">Example</checkBox_2>
    <checkBox_3 boolean="true">EVILEG</checkBox_3>
</resources>

Ergebnis

Das Ergebnis sollte eine Anwendung sein, die eine XML-Datei erstellt oder neu schreibt, Daten aus Kontrollkästchen und den entsprechenden lineEdit -Feldern nimmt und diese XML-Datei mit dem Setzen der Daten in den Feldern Checkboxen und lineEdit .

Anwendung zum Arbeiten mit XML-Dateien

Рекомендуємо хостинг TIMEWEB
Рекомендуємо хостинг TIMEWEB
Stabiles Hosting des sozialen Netzwerks EVILEG. Wir empfehlen VDS-Hosting für Django-Projekte.

Magst du es? In sozialen Netzwerken teilen!

C
  • 20. Januar 2017 13:40

Не могли бы предоставить пример, где больше уровней в xml файле?

Evgenii Legotckoi
  • 20. Januar 2017 23:48

Это конечно можно, но насколько больше? И применительно к какому виду... Всё упирается же в то, куда именно будет этот XML применяться.

Например, чтение данных из XML можно сделать и с помощью QDomDocument. А если учесть, что SVG файл также фактически является XML документом, то Вы можете посмотреть следующий пример, для ознакомления с вытягиванием данных из XML файла:

SvgReader на Qt. Восстановление данных из файла SVG в QGraphicsScene

Kommentare

Nur autorisierte Benutzer können Kommentare posten.
Bitte Anmelden oder Registrieren
Letzte Kommentare
A
ALO1ZE19. Oktober 2024 08:19
Fb3-Dateileser auf Qt Creator Подскажите как это запустить? Я не шарю в программировании и кодинге. Скачал и установаил Qt, но куча ошибок выдается и не запустить. А очень надо fb3 переконвертировать в html
ИМ
Игорь Максимов5. Oktober 2024 07:51
Django – Lektion 064. So schreiben Sie eine Python-Markdown-Erweiterung Приветствую Евгений! У меня вопрос. Можно ли вставлять свои классы в разметку редактора markdown? Допустим имея стандартную разметку: <ul> <li></li> <li></l…
d
dblas55. Juli 2024 11:02
QML - Lektion 016. SQLite-Datenbank und das Arbeiten damit in QML Qt Здравствуйте, возникает такая проблема (я новичок): ApplicationWindow неизвестный элемент. (М300) для TextField и Button аналогично. Могу предположить, что из-за более новой верси…
k
kmssr8. Februar 2024 18:43
Qt Linux - Lektion 001. Autorun Qt-Anwendung unter Linux как сделать автозапуск для флэтпака, который не даёт создавать файлы в ~/.config - вот это вопрос ))
Qt WinAPI - Lektion 007. Arbeiten mit ICMP-Ping in Qt Без строки #include <QRegularExpressionValidator> в заголовочном файле не работает валидатор.
Jetzt im Forum diskutieren
J
JacobFib17. Oktober 2024 03:27
добавить qlineseries в функции Пользователь может получить любые разъяснения по интересующим вопросам, касающимся обработки его персональных данных, обратившись к Оператору с помощью электронной почты https://topdecorpro.ru…
JW
Jhon Wick1. Oktober 2024 15:52
Indian Food Restaurant In Columbus OH| Layla’s Kitchen Indian Restaurant If you're looking for a truly authentic https://www.laylaskitchenrestaurantohio.com/ , Layla’s Kitchen Indian Restaurant is your go-to destination. Located at 6152 Cleveland Ave, Colu…
КГ
Кирилл Гусарев27. September 2024 09:09
Не запускается программа на Qt: точка входа в процедуру не найдена в библиотеке DLL Написал программу на C++ Qt в Qt Creator, сбилдил Release с помощью MinGW 64-bit, бинарнику напихал dll-ки с помощью windeployqt.exe. При попытке запуска моей сбилженной программы выдаёт три оши…
F
Fynjy22. Juli 2024 04:15
при создании qml проекта Kits есть но недоступны для выбора Поставил Qt Creator 11.0.2. Qt 6.4.3 При создании проекта Qml не могу выбрать Kits, они все недоступны, хотя настроены и при создании обычного Qt Widget приложения их можно выбрать. В чем может …

Folgen Sie uns in sozialen Netzwerken