首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >自定义类型的Qt QMetaType序列化和QVariant

自定义类型的Qt QMetaType序列化和QVariant
EN

Stack Overflow用户
提问于 2011-04-20 08:02:53
回答 3查看 3.1K关注 0票数 0

我希望访问QSettings和QVariant使用的序列化技术。例如,如果创建一个QRect对象并使用QSettings将其存储到INI文件中,则会得到如下所示的行:

代码语言:javascript
复制
value=@Rect(1 2 3 4)

大多数标准Qt类型和自定义类型都具有类似的字符串序列化格式来保存/加载。我怎么能做同样的事?

也就是说,我有一个QVariant,希望保存它包含的数据,然后再加载该数据。保存的表单应该是文本数据(如上面的数据),以便在正常配置文件(如INI)或注册表中使用。

嗯,我看了一下QSettings源代码,它只是对一些常见类型进行了硬编码处理,然后对其他类型使用了QDataStream。这意味着不存在以文本形式序列化数据的通用方法。

EN

回答 3

Stack Overflow用户

发布于 2021-02-01 21:52:46

Qt元对象系统能够为自定义类型注册大量操作符。其中之一就是StreamOperator。QSettings使用此操作符在配置文件中写入和读取QVariant。

因此,首先,您需要为自定义类型实现两个流运算符,如@divanov所述

代码语言:javascript
复制
QDataStream & operator<< ( QDataStream & stream, const YourClass & yourObject );
QDataStream & operator>> ( QDataStream & stream, YourClass & yourObject );

之后,您需要使用qRegisterMetaTypeStreamOperators.将这两个自定义类型的运算符注册到Qt元对象系统。

下面的示例描述了前面提到的使用自定义类型Color的所有步骤。

代码语言:javascript
复制
#include <QMetaType>
#include <QDataStream>
#include <QSettings>
#include <cassert>

// Custom type 'Color'
struct Color
{
  uint8_t _red;
  uint8_t _green;
  uint8_t _blue;

  // Stream operator used by QSettings to save a value of type Color 
  // to configuration file 
  friend QDataStream& operator<<(QDataStream& out, const Color& color)
  {
      out << color._red;
      out << color._green;
      out << color._blue;
      return out;
  }

  // Stream operator used by QSettings to load a value of type Color 
  // from a configuration file
  friend QDataStream& operator>>(QDataStream& in, Color& color)
  {
    in >> color._red;
    in >> color._green;
    in >> color._blue;
    return in;
  }
};

Q_DECLARE_METATYPE( Color )

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

  // Register Color to qt meta-object system
  qRegisterMetaType<Color>();
 
  // Register its two streams operator to qt meta-object system
  qRegisterMetaTypeStreamOperators<Color>();

  // Test it with QSettings!
  QSettings configFile("config.ini");

  // Save the color
  Color saveColor { 12,  13,  14 };
  configFile.setValue("Color", QVariant::fromValue(saveColor));

  // Load the color
  Color loadColor = configFile.value("Color", QVariant()).value<Color>();

  // Asserts are successful
  assert(loadColor._red == 12);
  assert(loadColor._green == 13);
  assert(loadColor._blue == 14);
}
票数 1
EN

Stack Overflow用户

发布于 2011-04-20 08:13:50

QDataStream类向QIODevice提供二进制数据的序列化。您应该实现两个操作符:

代码语言:javascript
复制
QDataStream & operator<< ( QDataStream & stream, const YourClass & yourObject );
QDataStream & operator>> ( QDataStream & stream, YourClass & yourObject );

将负责数据的序列化和反序列化。

阅读有关Qt中序列化的更多信息。

如果您对文本序列化感兴趣,那么应该选择QTextStream作为您的工具。但是,大多数类都没有能够处理文本流的运算符,因此您必须实现它们。

票数 0
EN

Stack Overflow用户

发布于 2021-02-01 23:29:37

就我个人而言,我发现QVariantMapQVariantList对于这类事情非常方便。向类/结构提供转换函数:

代码语言:javascript
复制
class User {
public:
    QVariantMap toVariantMap() const {
        QVariantMap map;
        map["name"] = m_name;
        map["reputation"] = m_reputation;
        map["tags"] = m_tags;

        return map;
    }

    static User fromVariantMap(const QVariantMap& map) {
        User user;
        user.m_name = map["name"].toString();
        user.m_reputation = map["reputation"].toInt();
        user.m_tags = map["tags"].toStringList();
        return user;
    }

private:
    QString m_name;
    int m_reputation;
    QStringList m_tags;
} 

toVariantMap保存它

代码语言:javascript
复制
settings->setValue("user", user.toVariantMap());

fromVariantMap获取它

代码语言:javascript
复制
auto user = User::fromVariantMap(settings->value("user").toVariantMap());

要保存QString以外的项目列表,可以使用QVariantList:

代码语言:javascript
复制
QVariantList list;
for (int i = 0; i < m_list.size(); ++i)
    list.append(m_list[i]);
map["list"] = list;
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5727277

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档