Qt 窗口界面值的保存与加载

内容由deepseek直接输出:

头文件:

#ifndef WIDGETJSONHELPER_H
#define WIDGETJSONHELPER_H


#include <QObject>
#include <QJsonArray>
#include <QJsonObject>
#include <QJsonDocument>
#include <QFile>
#include <QWidget>
#include <QLineEdit>
#include <QTextEdit>
#include <QComboBox>
#include <QCheckBox>
#include <QRadioButton>
#include <QSpinBox>
#include <QDoubleSpinBox>
#include <QSlider>
#include <QDateTimeEdit>
#include <QGroupBox>
#include <QTabWidget>
#include <QListWidget>
#include <QTableWidget>
#include <QDebug>

class WidgetJsonHelper
{
public:

    WidgetJsonHelper();

    // 保存控件值到JSON文件
    static bool saveToJson(QWidget* widget, const QString& filePath, bool saveGeometry = false);

    // 从JSON文件加载控件值
    static bool loadFromJson(QWidget* widget, const QString& filePath, bool loadGeometry = false);

private:
    // 递归序列化控件及其子控件
    static void serializeWidget(QObject* obj, QJsonObject& jsonObj);

    // 递归反序列化控件值
    static void deserializeWidget(QObject* obj, const QJsonObject& jsonObj);
};

#endif // WIDGETJSONHELPER_H

源文件:

#include "widgetjsonhelper.h"

WidgetJsonHelper::WidgetJsonHelper()
{

}

bool WidgetJsonHelper::saveToJson(QWidget *widget, const QString &filePath, bool saveGeometry)
{
    QJsonObject jsonObj;

    // 保存控件值
    serializeWidget(widget, jsonObj);

    // 可选保存窗口几何信息
    if (saveGeometry) {
        QJsonObject geometryObj;
        geometryObj["x"] = widget->x();
        geometryObj["y"] = widget->y();
        geometryObj["width"] = widget->width();
        geometryObj["height"] = widget->height();
        geometryObj["isMaximized"] = widget->isMaximized();
        jsonObj["__geometry__"] = geometryObj;
    }

    // 写入文件
    QJsonDocument doc(jsonObj);
    QFile file(filePath);
    if (!file.open(QIODevice::WriteOnly)) {
        qWarning() << "Failed to open file for writing:" << filePath;
        return false;
    }

    file.write(doc.toJson());
    file.close();
    return true;
}

bool WidgetJsonHelper::loadFromJson(QWidget *widget, const QString &filePath, bool loadGeometry)
{
    QFile file(filePath);
    if (!file.open(QIODevice::ReadOnly)) {
        qWarning() << "Failed to open file for reading:" << filePath;
        return false;
    }

    QByteArray data = file.readAll();
    file.close();

    QJsonDocument doc = QJsonDocument::fromJson(data);
    if (doc.isNull()) {
        qWarning() << "Invalid JSON document";
        return false;
    }

    QJsonObject jsonObj = doc.object();

    // 恢复控件值
    deserializeWidget(widget, jsonObj);

    // 可选恢复窗口几何信息
    if (loadGeometry && jsonObj.contains("__geometry__")) {
        QJsonObject geometryObj = jsonObj["__geometry__"].toObject();
        int x = geometryObj["x"].toInt();
        int y = geometryObj["y"].toInt();
        int width = geometryObj["width"].toInt();
        int height = geometryObj["height"].toInt();
        bool isMaximized = geometryObj["isMaximized"].toBool();

        if (!isMaximized) {
            widget->setGeometry(x, y, width, height);
        } else {
            widget->showMaximized();
        }
    }

    return true;
}

void WidgetJsonHelper::serializeWidget(QObject *obj, QJsonObject &jsonObj)
{
    if (!obj || obj->objectName().isEmpty()) return;

    // 根据控件类型处理值
    if (QLineEdit* lineEdit = qobject_cast<QLineEdit*>(obj)) {
        jsonObj[lineEdit->objectName()] = lineEdit->text();
    }
    else if (QTextEdit* textEdit = qobject_cast<QTextEdit*>(obj)) {
        jsonObj[textEdit->objectName()] = textEdit->toPlainText();
    }
    else if (QComboBox* comboBox = qobject_cast<QComboBox*>(obj)) {
        jsonObj[comboBox->objectName()] = comboBox->currentIndex();
        // 保存所有项和当前选中项
        QJsonArray items;
        for (int i = 0; i < comboBox->count(); ++i) {
            items.append(comboBox->itemText(i));
        }
        jsonObj[comboBox->objectName() + "_items"] = items;
    }
    else if (QCheckBox* checkBox = qobject_cast<QCheckBox*>(obj)) {
        jsonObj[checkBox->objectName()] = checkBox->isChecked();
    }
    else if (QRadioButton* radioButton = qobject_cast<QRadioButton*>(obj)) {
        jsonObj[radioButton->objectName()] = radioButton->isChecked();
    }
    else if (QSpinBox* spinBox = qobject_cast<QSpinBox*>(obj)) {
        jsonObj[spinBox->objectName()] = spinBox->value();
    }
    else if (QDoubleSpinBox* doubleSpinBox = qobject_cast<QDoubleSpinBox*>(obj)) {
        jsonObj[doubleSpinBox->objectName()] = doubleSpinBox->value();
    }
    else if (QSlider* slider = qobject_cast<QSlider*>(obj)) {
        jsonObj[slider->objectName()] = slider->value();
    }
    else if (QDateTimeEdit* dateTimeEdit = qobject_cast<QDateTimeEdit*>(obj)) {
        jsonObj[dateTimeEdit->objectName()] = dateTimeEdit->dateTime().toString(Qt::ISODate);
    }
    else if (QGroupBox* groupBox = qobject_cast<QGroupBox*>(obj)) {
        jsonObj[groupBox->objectName()] = groupBox->isChecked();
    }
    else if (QListWidget* listWidget = qobject_cast<QListWidget*>(obj)) {
        QJsonArray selectedItems;
        foreach (QListWidgetItem* item, listWidget->selectedItems()) {
            selectedItems.append(listWidget->row(item));
        }
        jsonObj[listWidget->objectName()] = selectedItems;
    }
    else if (QTableWidget* tableWidget = qobject_cast<QTableWidget*>(obj)) {
        QJsonObject tableData;
        tableData["rowCount"] = tableWidget->rowCount();
        tableData["columnCount"] = tableWidget->columnCount();

        QJsonArray cellData;
        for (int row = 0; row < tableWidget->rowCount(); ++row) {
            for (int col = 0; col < tableWidget->columnCount(); ++col) {
                QTableWidgetItem* item = tableWidget->item(row, col);
                if (item) {
                    QJsonObject cell;
                    cell["row"] = row;
                    cell["column"] = col;
                    cell["text"] = item->text();
                    cell["flags"] = static_cast<int>(item->flags());
                    cellData.append(cell);
                }
            }
        }
        tableData["cells"] = cellData;
        jsonObj[tableWidget->objectName()] = tableData;
    }
    // 可以继续添加更多控件类型的处理...

    // 递归处理子对象
    for (QObject* child : obj->children()) {
        if (child->isWidgetType()) {
            QJsonObject childObj;
            serializeWidget(child, childObj);
            if (!childObj.isEmpty()) {
                jsonObj[child->objectName()] = childObj;
            }
        }
    }
}

void WidgetJsonHelper::deserializeWidget(QObject *obj, const QJsonObject &jsonObj)
{
    if (!obj || obj->objectName().isEmpty()) return;

    QString objName = obj->objectName();

    if (jsonObj.contains(objName)) {
        if (QLineEdit* lineEdit = qobject_cast<QLineEdit*>(obj)) {
            lineEdit->setText(jsonObj[objName].toString());
        }
        else if (QTextEdit* textEdit = qobject_cast<QTextEdit*>(obj)) {
            textEdit->setPlainText(jsonObj[objName].toString());
        }
        else if (QComboBox* comboBox = qobject_cast<QComboBox*>(obj)) {
            int index = jsonObj[objName].toInt();
            if (index >= 0 && index < comboBox->count()) {
                comboBox->setCurrentIndex(index);
            }
            // 如果有保存的项,恢复它们
            if (jsonObj.contains(objName + "_items")) {
                QJsonArray items = jsonObj[objName + "_items"].toArray();
                comboBox->clear();
                foreach (const QJsonValue& item, items) {
                    comboBox->addItem(item.toString());
                }
                if (index >= 0 && index < comboBox->count()) {
                    comboBox->setCurrentIndex(index);
                }
            }
        }
        else if (QCheckBox* checkBox = qobject_cast<QCheckBox*>(obj)) {
            checkBox->setChecked(jsonObj[objName].toBool());
        }
        else if (QRadioButton* radioButton = qobject_cast<QRadioButton*>(obj)) {
            radioButton->setChecked(jsonObj[objName].toBool());
        }
        else if (QSpinBox* spinBox = qobject_cast<QSpinBox*>(obj)) {
            spinBox->setValue(jsonObj[objName].toInt());
        }
        else if (QDoubleSpinBox* doubleSpinBox = qobject_cast<QDoubleSpinBox*>(obj)) {
            doubleSpinBox->setValue(jsonObj[objName].toDouble());
        }
        else if (QSlider* slider = qobject_cast<QSlider*>(obj)) {
            slider->setValue(jsonObj[objName].toInt());
        }
        else if (QDateTimeEdit* dateTimeEdit = qobject_cast<QDateTimeEdit*>(obj)) {
            QDateTime dt = QDateTime::fromString(jsonObj[objName].toString(), Qt::ISODate);
            if (dt.isValid()) {
                dateTimeEdit->setDateTime(dt);
            }
        }
        else if (QGroupBox* groupBox = qobject_cast<QGroupBox*>(obj)) {
            groupBox->setChecked(jsonObj[objName].toBool());
        }
        else if (QListWidget* listWidget = qobject_cast<QListWidget*>(obj)) {
            QJsonArray selectedItems = jsonObj[objName].toArray();
            listWidget->clearSelection();
            foreach (const QJsonValue& item, selectedItems) {
                int row = item.toInt();
                if (row >= 0 && row < listWidget->count()) {
                    listWidget->item(row)->setSelected(true);
                }
            }
        }
        else if (QTableWidget* tableWidget = qobject_cast<QTableWidget*>(obj)) {
            QJsonObject tableData = jsonObj[objName].toObject();
            int rowCount = tableData["rowCount"].toInt();
            int columnCount = tableData["columnCount"].toInt();

            tableWidget->setRowCount(rowCount);
            tableWidget->setColumnCount(columnCount);

            QJsonArray cellData = tableData["cells"].toArray();
            foreach (const QJsonValue& cellValue, cellData) {
                QJsonObject cell = cellValue.toObject();
                int row = cell["row"].toInt();
                int col = cell["column"].toInt();
                QString text = cell["text"].toString();
                Qt::ItemFlags flags = static_cast<Qt::ItemFlags>(cell["flags"].toInt());

                QTableWidgetItem* item = new QTableWidgetItem(text);
                item->setFlags(flags);
                tableWidget->setItem(row, col, item);
            }
        }
        // 可以继续添加更多控件类型的处理...
    }

    // 递归处理子对象
    for (QObject* child : obj->children()) {
        if (child->isWidgetType()) {
            QString childName = child->objectName();
            if (!childName.isEmpty() && jsonObj.contains(childName)) {
                if (jsonObj[childName].isObject()) {
                    deserializeWidget(child, jsonObj[childName].toObject());
                }
            }
        }
    }
}

 

posted on 2025-04-09 15:04  明太宗朱棣  阅读(43)  评论(0)    收藏  举报

导航