我有一个整数对列表,我想用持久的方式存储,使用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);
}
答案 0 :(得分:4)
您根本没有任何兼容的隐式转化。编译器不知道如何将列表转换为变体。
事实上,Q_DECLARE_METATYPE
根本没有必要,至少对我来说,以下代码编译时没有错误:
QSettings s;
QList< QPair < int,int>> l;
s.setValue("key", QVariant::fromValue(l));
编辑:虽然它没有得到编译错误,但它仍然会收到运行时错误,因为它不知道如何序列化和反序列化int对列表。所以你必须告诉它如何:
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;
}
并且还为元系统中的类型注册流操作符:
qRegisterMetaTypeStreamOperators<QList<QPair<int,int>>>("whatever");
Aaand ..它有效!
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
答案 1 :(得分:1)
请看这里:http://doc.qt.io/qt-5/qvariant.html
您可以在QVariant中存储的唯一QList类型是QList<QVariant>
,即变体可以是变体列表。
因此,您需要将QList<QPair<int, int>>
替换为QList<QVariant>
,并且作为该列表中的变体,您可以存储qulonglong
这是一个64位整数,您可以在其中打包你的两个32位整数,或找出一些其他方案(包括列表列表,其中每个子列表的长度为2,并存储为QVariant)。
作为替代方案,请使用QList<QJsonDocument>
,并将所有设置存储为JSON。