当前位置: 首页 > article >正文

复杂的QVariant写入文件以及从文件中读入复原

将复杂的QVariant写入Json文件

要将复杂的 QVariant(包含 QListQMap 等)写入 JSON 文件,你可以借助 Qt 的 QJsonDocumentQJsonObjectQJsonArrayQVariant 转换为 JSON 格式。以下是实现代码:


实现代码:

#include <QVariant>
#include <QFile>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>
#include <QDebug>

// 辅助函数:递归将 QVariant 转换为 QJsonValue
QJsonValue variantToJsonValue(const QVariant &variant) {
    switch (variant.type()) {
        case QVariant::Map: {
            QJsonObject jsonObj;
            QMap<QString, QVariant> map = variant.toMap();
            for (auto it = map.begin(); it != map.end(); ++it) {
                jsonObj.insert(it.key(), variantToJsonValue(it.value()));
            }
            return jsonObj;
        }
        case QVariant::List: {
            QJsonArray jsonArray;
            QList<QVariant> list = variant.toList();
            for (const QVariant &item : list) {
                jsonArray.append(variantToJsonValue(item));
            }
            return jsonArray;
        }
        case QVariant::String:
            return QJsonValue(variant.toString());
        case QVariant::Int:
            return QJsonValue(variant.toInt());
        case QVariant::Double:
            return QJsonValue(variant.toDouble());
        case QVariant::Bool:
            return QJsonValue(variant.toBool());
        default:
            // 对于其他类型,尝试将其转换为字符串
            if (variant.canConvert<QString>()) {
                return QJsonValue(variant.toString());
            } else {
                return QJsonValue(); // 空值
            }
    }
}

// 写入 QVariant 到 JSON 文件
void writeVariantToJsonFile(const QVariant &variant, const QString &filePath) {
    // 将 QVariant 转换为 QJsonValue
    QJsonValue jsonValue = variantToJsonValue(variant);

    // 判断是否是对象或数组,否则包装成对象
    QJsonDocument jsonDoc;
    if (jsonValue.isObject()) {
        jsonDoc = QJsonDocument(jsonValue.toObject());
    } else if (jsonValue.isArray()) {
        jsonDoc = QJsonDocument(jsonValue.toArray());
    } else {
        QJsonObject wrapper;
        wrapper.insert("value", jsonValue);
        jsonDoc = QJsonDocument(wrapper);
    }

    // 将 JSON 写入文件
    QFile file(filePath);
    if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
        qWarning() << "无法打开文件:" << filePath;
        return;
    }

    file.write(jsonDoc.toJson(QJsonDocument::Indented)); // 格式化输出
    file.close();
}

// 示例主函数
int main() {
    // 构造一个复杂的 QVariant 数据结构
    QVariantMap map;
    map["key1"] = "value1";
    map["key2"] = 42;
    map["key3"] = QVariantList{"item1", "item2", 123, QVariantMap{{"nestedKey", "nestedValue"}}};
    map["key4"] = QVariantMap{{"subKey1", "subValue1"}, {"subKey2", 99}};
    map["key5"] = true;

    QVariant complexVariant = map;

    // 写入文件
    QString filePath = "output.json";
    writeVariantToJsonFile(complexVariant, filePath);

    qDebug() << "复杂 QVariant 已写入 JSON 文件:" << filePath;
    return 0;
}

说明:

  1. 核心方法:variantToJsonValue

    • 这是一个递归函数,将 QVariant 转换为 QJsonValue
    • 支持以下类型:
      • QVariant::Map -> 转换为 QJsonObject
      • QVariant::List -> 转换为 QJsonArray
      • 基本类型(QStringintdoublebool) -> 转换为对应的 JSON 值
      • 对于其他类型,尝试调用 toString() 进行转换,如果不支持则写入空值。
  2. JSON 文件写入:writeVariantToJsonFile

    • 使用 QJsonDocumentQJsonValue 写入 JSON 文件。
    • 自动判断数据结构是 JSON 对象还是数组,如果是其他类型,则将其包装为一个 JSON 对象。
    • 通过 QJsonDocument::Indented 格式化输出,生成可读性更高的 JSON 文件。
  3. 支持的类型

    • QVariantMap -> JSON 对象
    • QVariantList -> JSON 数组
    • 基本类型(QStringintdoublebool 等)
  4. 输出示例
    假设输入的 QVariant 是如下结构:

    QVariantMap map;
    map["key1"] = "value1";
    map["key2"] = 42;
    map["key3"] = QVariantList{"item1", "item2", 123, QVariantMap{{"nestedKey", "nestedValue"}}};
    map["key4"] = QVariantMap{{"subKey1", "subValue1"}, {"subKey2", 99}};
    map["key5"] = true;
    

    输出的 output.json 文件内容为:

    {
        "key1": "value1",
        "key2": 42,
        "key3": [
            "item1",
            "item2",
            123,
            {
                "nestedKey": "nestedValue"
            }
        ],
        "key4": {
            "subKey1": "subValue1",
            "subKey2": 99
        },
        "key5": true
    }
    
  5. 注意事项

    • 如果文件路径无效或者没有写入权限,会发出警告。
    • QVariant 中包含无法识别的类型时,将尝试将其转换为字符串,否则写入空值。

使用方法:

将上述代码复制并运行,程序会将复杂的 QVariant 数据结构写入 output.json 文件,你可以用任意文本编辑器或 JSON 查看器打开文件查看结果。

从Json文件中复原QVariant

要将刚才写入的 JSON 文件重新读入到程序中,并解析为一个 QVariant 数据结构,可以使用 Qt 的 QJsonDocumentQJsonObject/QJsonArray 类。以下是实现代码:


实现代码:

#include <QVariant>
#include <QFile>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>
#include <QDebug>

// 辅助函数:递归将 QJsonValue 转换为 QVariant
QVariant jsonValueToVariant(const QJsonValue &jsonValue) {
    if (jsonValue.isObject()) {
        QVariantMap map;
        QJsonObject obj = jsonValue.toObject();
        for (auto it = obj.begin(); it != obj.end(); ++it) {
            map.insert(it.key(), jsonValueToVariant(it.value()));
        }
        return map;
    } else if (jsonValue.isArray()) {
        QVariantList list;
        QJsonArray array = jsonValue.toArray();
        for (const QJsonValue &item : array) {
            list.append(jsonValueToVariant(item));
        }
        return list;
    } else if (jsonValue.isString()) {
        return jsonValue.toString();
    } else if (jsonValue.isDouble()) {
        return jsonValue.toDouble();
    } else if (jsonValue.isBool()) {
        return jsonValue.toBool();
    } else if (jsonValue.isNull()) {
        return QVariant(); // 空值
    }
    return QVariant();
}

// 从 JSON 文件中读取内容并转换为 QVariant
QVariant readJsonFileToVariant(const QString &filePath) {
    QFile file(filePath);
    if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
        qWarning() << "无法打开文件:" << filePath;
        return QVariant();
    }

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

    QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonData);
    if (jsonDoc.isNull()) {
        qWarning() << "JSON 文件格式错误:" << filePath;
        return QVariant();
    }

    // 根据 JSON 类型返回 QVariant
    if (jsonDoc.isObject()) {
        return jsonValueToVariant(jsonDoc.object());
    } else if (jsonDoc.isArray()) {
        return jsonValueToVariant(jsonDoc.array());
    }

    return QVariant(); // 不支持的 JSON 格式
}

// 示例主函数
int main() {
    // 写入 JSON 文件路径
    QString filePath = "output.json";

    // 从 JSON 文件中读取并解析为 QVariant
    QVariant variant = readJsonFileToVariant(filePath);

    // 打印解析结果
    qDebug() << "从 JSON 文件解析出的 QVariant 数据:";
    qDebug() << variant;

    // 如果需要递归打印,可以使用 QVariant 的转字符串函数(如前所述的 variantToString)

    return 0;
}

说明:

  1. 核心方法:jsonValueToVariant

    • 递归地将 QJsonValue 转换为 QVariant
    • 支持以下类型:
      • QJsonObject -> 转换为 QVariantMap
      • QJsonArray -> 转换为 QVariantList
      • 基本类型(字符串、数字、布尔值等) -> 转换为对应的 QVariant 类型
      • 空值(null) -> 转换为默认的 QVariant()
  2. 从 JSON 文件读取:readJsonFileToVariant

    • 读取 JSON 文件内容到内存。
    • 使用 QJsonDocument::fromJson 解析为 QJsonDocument
    • 根据 JSON 数据的类型(对象或数组)调用 jsonValueToVariant 进行递归转换。
  3. 输出示例
    如果文件 output.json 的内容是:

    {
        "key1": "value1",
        "key2": 42,
        "key3": [
            "item1",
            "item2",
            123,
            {
                "nestedKey": "nestedValue"
            }
        ],
        "key4": {
            "subKey1": "subValue1",
            "subKey2": 99
        },
        "key5": true
    }
    

    那么读取后的 QVariant 数据结构为:

    QVariantMap {
        "key1": "value1",
        "key2": 42,
        "key3": QVariantList {
            "item1",
            "item2",
            123,
            QVariantMap {
                "nestedKey": "nestedValue"
            }
        },
        "key4": QVariantMap {
            "subKey1": "subValue1",
            "subKey2": 99
        },
        "key5": true
    }
    

    通过 qDebug() 输出为:

    QMap(("key1", QVariant(QString, "value1"))
         ("key2", QVariant(int, 42))
         ("key3", QVariant(QVariantList, ("item1", "item2", 123, QVariant(QVariantMap, QMap(("nestedKey", QVariant(QString, "nestedValue")))))))
         ("key4", QVariant(QVariantMap, QMap(("subKey1", QVariant(QString, "subValue1")) ("subKey2", QVariant(int, 99)))))
         ("key5", QVariant(bool, true)))
    
  4. 注意事项

    • 如果文件路径无效或文件格式错误,程序会输出警告。
    • 解析过程中如果遇到不支持的类型,将尝试返回空值。

使用方法:

  1. 运行程序,它会尝试读取 output.json 文件。
  2. 解析后的 QVariant 数据可以直接在程序中使用,也可以通过递归打印函数(如之前的 variantToString)格式化输出。

这样,你就可以将写入的 JSON 文件完整地读取回内存,并转换为 QVariant 数据结构。


http://www.kler.cn/a/459861.html

相关文章:

  • Ps:创建数据驱动的图像
  • Elasticsearch:基础概念
  • Django-Easy-Audit 实战:轻松实现数据审计
  • C++ 设计模式:模板方法(Template Method)
  • Java List 集合详解:基础用法、常见实现类与高频面试题解析
  • Linux(Ubuntu)下ESP-IDF下载与安装完整流程(2)
  • PCL点云库入门——PCL库点云滤波算法之体素滤波(VoxelGrid)
  • Unity学习笔记(四)如何实现角色攻击、组合攻击
  • Jenkins使用记录
  • FPGA多路MIPI转FPD-Link视频缩放拼接显示,基于IMX327+FPD953架构,提供2套工程源码和技术支持
  • 使用 Scrapy 抓取网页数据
  • WebRTC:实现浏览器与移动应用的实时通信
  • 【Unity】 HTFramework框架(五十七)通过Tag、Layer批量搜索物体
  • Perl语言的软件工程
  • 自动化办公-将 Excel 的 Sheet 页拆分成单独的 Excel 文件
  • chatgpt model spec 2024
  • ubuntu20.04 调试bcache源码
  • 【C++】BC89 包含数字9的数
  • Docker搭建MySQL
  • C++ 设计模式:命令模式(Command Pattern)
  • Python 网络爬虫 全面解析
  • 基于Spring Boot的宠物领养系统的设计与实现(代码+数据库+LW)
  • 2025新一代智能终端发展全面解析:技术创新、应用拓展与产业生态演变
  • window如何将powershell以管理员身份添加到右键菜单?(按住Shift键显示)
  • git将本地项目上传到远程仓库
  • HCIA笔记10--VLAN间互访、PPPoE协议