【问题标题】:Why I can't store QVariantMap in QSettings?为什么我不能在 QSettings 中存储 QVariantMap?
【发布时间】:2018-10-12 10:57:04
【问题描述】:

为什么是possible in Qt 5.2previously 并以以下格式存储数据:

key=@Variant(\0\0\0\b\0\0\0)

但是现在 Qt 5.11 有问题?!以下代码

QVariantMap projectsMap;
for (auto project : projects)
    projectsMap.insert(key, value);

settings->setValue("Group/projects", projectsMap);

可以正确执行,但不会将任何内容存储到 ini 文件中。

qRegisterMetaTypeStreamOperators<QVariantMap>("QVariantMap");

也无济于事。这个怎么存储,这里有什么问题?

【问题讨论】:

  • 无法重现(Linux + Qt5.11.2)。 projectsMap肯定不是空的吗? QVariant 实例中包含的类型是否都向Qt 元类型系统注册?
  • @G.M.,是的,不是空的:用qDebug()检查这个包含键和值的QString。问题是即使 "projects" 密钥也没有在 ini 文件中的 "Group" 中创建。
  • @G.M.,问题出在settings->sync():上面设置在析构函数中执行的存储操作,我认为设置析构函数应该自动调用sync() - 似乎不是这样,所以明确调用sync()现在 - 工作正常!谢谢!
  • 在提供完整的测试用例之前,这个问题是有缺陷的。您在哪个“析构函数”中设置了设置?析构函数在这里并不特殊,QSettings 也不在乎。
  • @KubaOber,在我的类设置中声明为QPointer<QSettings> settings; 并且似乎在销毁对象settings->sync() 时没有被调用。明确地调用它。

标签: qt qt5 qmap qvariant qsettings


【解决方案1】:

不要存储QSettings:它不应该以这种方式使用。每次更改设置时都应使用 QSettings 的新实例。您的析构函数应如下所示:

MyClass::~MyClass() {
  QSettings s;
  s.setValue(kFoo, this->m_bar);
  …
}

QSettings 是设置系统的临时句柄,它的实例化很便宜。你泄露它是因为QPointer 不会破坏任何东西:它不是一个拥有指针。

【讨论】:

  • 我明白了,我错过了关于QPointer 的信息,现在我明白为什么人们在Qt 应用程序中使用std::unique_ptr 作为QPointer 不是类似物。将更改为std::unique_ptr 以自动清理对象。您的方式对我不起作用,因为设置对象由管理器类拥有并在许多受控类之间共享。只需要正确清除设置对象 - 将为此使用 std::unique_ptr 或仅使用 QSettings settings; 作为 unique_ptr 不如 QPointer 方便。
  • 我告诉你,你不应该对设置对象这样做!不要“管理它”!您正在为自己发明甚至不应该尝试的工作。每次你想使用它时实例化它。它旨在以这种方式使用。而不是使用指针,您应该按值存储内容。指针的目的是什么?没有。仅使用对象生命周期的指针与“管理器”的生命周期不同。在现代 C++ 中,大多数这样的“管理器”应该是一个带有值的简单结构,其中一些可能包含在 optional 中。
  • 受控对象对设置一无所知,不要持有它们,通过 manager()->setting()-> 访问这就是我需要指针的原因:在管理器和受控对象之间共享单个设置实例。
  • 受控对象应在需要时创建QSettings 的实例。如果setting() 返回的不是指向QSettings 的指针,即您自己的类,那么该类应根据需要临时创建设置对象。实际上,您可以将QSettings 包装在您自己的Settings 类中,以便其他对象可以使用;例如,此类将通过 getter/setter 间接公开设置。
  • 这个答案让我浪费了一些时间试图不使用QSettings *。那么,如果这不是它的预期用途呢? QThread 也没有被设计成在 run() 中有它的线程工作代码;但现在这是受支持的用法。 QSettings *pSettings; 对我来说很好用。我讨厌每次都设置所有参数。如果你 new 它,并传递给它一个父参数,它会自动处理任何需要发生的内存释放。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-03-17
  • 1970-01-01
  • 2020-10-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-30
相关资源
最近更新 更多