以人类可读的形式在 QSettings 中保存自定义 QMap 模板实例化

Posted

技术标签:

【中文标题】以人类可读的形式在 QSettings 中保存自定义 QMap 模板实例化【英文标题】:Save custom QMap template instantiation in QSettings in human-readable form 【发布时间】:2018-09-28 09:41:58 【问题描述】:

在我的代码中,我使用 QSettings 机制将我自己的类 MyClass 保存在 QMap<unsigned int, MyClass> 中并将其加载到配置文件中。

我知道如何将我自己的类型注册到 QMetaObject 以便我可以将它们与 QVariant 一起使用。这允许使用 QSettings 保存它们。请参阅下面的工作代码。

但是,这些类型在我正在写入的实际配置文件中的表示绝不是人类可读的。 是否有任何方法可以使自定义地图在文本编辑器中更具可读性,以便我可以在 Qt 之外手动更改配置?

将我的自定义类型保存到配置的代码:

struct MyClass

    unsigned int id;
    QString name;
    QString value;

    friend QDataStream & operator<< (QDataStream &arch, const MyClass& c)
    
        return arch << c.id << c.name << c.value;
    
    friend QDataStream & operator>> (QDataStream &arch, MyClass& c)
    
        return arch >> c.id >> c.name >> c.value;
    
;
Q_DECLARE_METATYPE(MyClass)
typedef QMap<unsigned int, MyClass> MyMap;

int main(int argc, char *argv[])

   MyMap map;
    map.insert(100, 100, "name1", "value1");
    map.insert(101, 101, "name2", "value2");
    map.insert(200, 200, "name3", "value3");

    qRegisterMetaTypeStreamOperators<MyMap>("MyMap");
    QSettings conf("/home/dave/temp/myfile.conf", QSettings::IniFormat);
    conf.setValue("myMapping", QVariant::fromValue(map));
    conf.sync();

编写的配置文件:

[General]
myMapping="@Variant(\0\0\0\x7f\0\0\0\x13QMap<uint,MyClass>\0\0\0\0\x3\0\0\0\xc8\0\0\0\xc8\0\0\0\n\0n\0\x61\0m\0\x65\0\x33\0\0\0\f\0v\0\x61\0l\0u\0\x65\0\x33\0\0\0\x65\0\0\0\x65\0\0\0\n\0n\0\x61\0m\0\x65\0\x32\0\0\0\f\0v\0\x61\0l\0u\0\x65\0\x32\0\0\0\x64\0\0\0\x64\0\0\0\n\0n\0\x61\0m\0\x65\0\x31\0\0\0\f\0v\0\x61\0l\0u\0\x65\0\x31)"

【问题讨论】:

【参考方案1】:

Qt 负责对您的地图进行序列化/反序列化 - 不幸的是,这并没有考虑到人类可读性。

您需要手动处理整个地图的序列化/反序列化并写入/读取 QString(或类似的东西),例如

QString serialize(const QMap<int, MyClass>& mapToSerialize)

    QStringList result;
    for(int key : mapToSerialize.keys())
    
        result.append("%1%2%3).arg(QString::number(i), SEPARATOR_TOKEN, serialize(mapToSerialize.value(i));
    
    return result.join(MAP_SEPARATOR_TOKEN);

这当然有缺点,您 1) 需要为地图和您的类编写序列化/反序列化函数,以及 2) 您需要处理所有特殊情况(转义特殊字符、解析错误数据等)

【讨论】:

以上是关于以人类可读的形式在 QSettings 中保存自定义 QMap 模板实例化的主要内容,如果未能解决你的问题,请参考以下文章

将 dict 保存为 JSON,以便它们是人类可读的 [重复]

如何以人类可读的格式输出(到日志)多级数组?

从 Play 商店更新我的应用程序后,如何在 Android 上保存 QSettings 文件的内容以使其可读?

Terraform 在自动化中计划人类可读的输出

人类可读的 GUID

格式化日期对象以显示人类可读的日期