将QPair的QList写入QSettings对象

问题描述 投票:2回答:2

我有一个整数对列表,我想用持久的方式存储,使用Qt Framework。

我想使用QList< QPair < int,int>>作为列表的类型,并使用QSettings将它们存储在.ini文件中。

不幸的是,函数QSettings::setValue引发了一个错误:

no matching function for call to ‘QSettings::setValue(const char [19], FavoriteList&)’
note:   no known conversion for argument 2 from QList< QPair< int, int> > to ‘const QVariant&’

它似乎无法将这种类型转换为QVariant。我尝试用Q_DECLARE_METATYPE声明它但它没有用,它引发了同样的错误。

如何将该类型写入QSettings对象?

编辑:失败的代码示例:

QList<QPair<int,int>> list;

if(!settings.contains("Radio/Favorites/FM"))
{
    settings.setValue("Radio/Favorites/FM", list);
}
c++ qt
2个回答
4
投票

您根本就没有任何兼容的隐式转换。编译器不知道如何将列表转换为变体。

事实上,qazxsw poi根本就没有必要,至少对我来说,以下代码编译时没有错误:

Q_DECLARE_METATYPE

编辑:虽然它没有得到编译错误,但它仍然会得到一个运行时错误,因为它不知道如何序列化和反序列化一对int对。所以你必须告诉它如何:

  QSettings s;
  QList< QPair < int,int>> l;
  s.setValue("key", QVariant::fromValue(l));

并且还为元系统中的类型注册流操作符:

QDataStream &operator<<(QDataStream &out, const QList<QPair<int,int>> &l) {
  int s = l.size();
  out << s;
  if (s) for (int i = 0; i < s; ++i) out << l[i].first << l[i].second;
  return out;
}
QDataStream &operator>>(QDataStream &in, QList<QPair<int,int>> &l) {
  if (!l.empty()) l.clear();
  int s;
  in >> s;
  if (s) {
    l.reserve(s);
    for (int i = 0; i < s; ++i) {
      int f, sec;
      in >> f >> sec;
      l.append(QPair<int, int>(f, sec));
    }
  }
  return in;
}

Aaand ..它有效!

qRegisterMetaTypeStreamOperators<QList<QPair<int,int>>>("whatever");

1
投票

看这里: QSettings s; QList<QPair<int,int>> l; l.append(QPair<int, int>(555, 556)); s.setValue("key", QVariant::fromValue(l)); QList<QPair<int,int>> l1 = s.value("key").value<QList<QPair<int,int>>>(); qDebug() << l1.at(0).first << l1.at(0).second; // 555 556

您可以存储在QVariant中的唯一类型的QList是http://doc.qt.io/qt-5/qvariant.html,即变体可以是变体列表。

所以你需要用QList<QVariant>替换你的QList<QPair<int, int>>,并且作为该列表中的变体,你可以存储一个64位整数的QList<QVariant>,你可以在其中打包你的两个32位整数,或者找出一些其他方案(包括列表列表,其中每个子列表的长度为2,并存储为QVariant)。

作为替代方案,使用qulonglong,并将所有设置存储为JSON。

© www.soinside.com 2019 - 2024. All rights reserved.