I want to persistently store a list of integer pairs, using Qt Framework.
I thought of using QList< QPair < int,int>>
as a type for the list, and to store them in an .ini
file using QSettings
.
Unfortunately, the function QSettings::setValue
raises an error:
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&’
It seems that it cannot cast that type to a QVariant
. I tried declaring it with Q_DECLARE_METATYPE
, but it didn't work, it raises the same error.
Example of code that fails:
QList<QPair<int,int>> list;
if(!settings.contains("Radio/Favorites/FM"))
{
settings.setValue("Radio/Favorites/FM", list);
}
How can I write that type to a QSettings
object?
You simply don't have any compatible implicit conversion. The compiler doesn't know how to turn your list to a variant.
In fact, Q_DECLARE_METATYPE
shoudln't be necessary at all, at least for me the following code compiles with no errors:
QSettings s;
QList< QPair < int,int>> l;
s.setValue("key", QVariant::fromValue(l));
EDIT: while it doesn't get compile errors, it will still get a runtime error because it doens't know how to serialize and deserialize a list of int pairs. So you will have to tell it how:
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;
}
And also register stream operators for the type in the meta system:
qRegisterMetaTypeStreamOperators<QList<QPair<int,int>>>("whatever");
Aaand.. it works!
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