我从 QSetting 读取自定义元类型数据时遇到问题。我有一堂课:
class MusicOwner
{
public:
MusicOwner() :
songs_count(0),
id(0)
{}
explicit MusicOwner(const Song &owner_radio);
Song toOwnerRadio() const;
static QList<MusicOwner> parseMusicOwnerList(const QVariant &request_result);
private:
friend QDataStream &operator <<(QDataStream &stream, const VkService::MusicOwner &val);
friend QDataStream &operator >>(QDataStream &stream, VkService::MusicOwner &val);
friend QDebug operator<< (QDebug d, const MusicOwner &owner);
int songs_count;
int id;
QString name;
QString screen_name;
QUrl photo;
};
Q_DECLARE_METATYPE(VkService::MusicOwner)
重载:
QDataStream &operator <<(QDataStream &stream, const VkService::MusicOwner &val)
{
stream << val.id;
stream << val.name;
stream << val.songs_count;
stream << val.screen_name;
return stream;
}
QDataStream &operator >>(QDataStream &stream, VkService::MusicOwner &val)
{
stream >> val.id;
stream >> val.name;
stream >> val.songs_count;
stream >> val.screen_name;
return stream;
}
QDebug operator <<(QDebug d, const VkService::MusicOwner &owner)
{
d << "MusicOwner("
<< owner.id << ","
<< owner.name << ","
<< owner.songs_count << ","
<< owner.screen_name << ")";
return d;
}
在程序开始的某个地方我打电话:
qRegisterMetaTypeStreamOperators<MusicOwner>("MusicOwner");
为了读写,我使用了两个功能:保存工作正常,我保存的所有数据都出现在设置文件中。
void VkService::SaveBookmarks()
{
TRACE;
QSettings s;
s.beginGroup(kSettingGroup);
s.beginWriteArray("bookmarks");
int index = 0;
for (int i = 0; i < root_item_->rowCount(); ++i){
auto item = root_item_->child(i);
if (item->data(InternetModel::Role_Type).toInt() == Type_Bookmark){
Song song = item->data(InternetModel::Role_SongMetadata).value<Song>();
s.setArrayIndex(index);
MusicOwner owner(song);
qLog(Info) << "Save" << index << ":" << owner;
s.setValue("owner", QVariant::fromValue(owner));
++index;
}
}
s.endArray();
}
此功能的问题,它的加载计数正确,但它正在加载空的默认构造项。
void VkService::LoadBookmarks()
{
QSettings s;
s.beginGroup(kSettingGroup);
int max = s.beginReadArray("bookmarks");
for (int i = 0; i < max; ++i){
s.setArrayIndex(i);
MusicOwner owner = s.value("owner").value<MusicOwner>();
qLog(Info) << "Load" << i << ":" << owner;
AppendBookmarkFromRadio(root_item_, owner.toOwnerRadio());
}
s.endArray();
}
我将其重写为新项目进行测试,但它工作正常。我花了两个小时来找出为什么这个变体能正确读取数据但第一个变体不能。第一个变体的所有者正确转换。甚至两个变体中的设置文件中的数据也相同。
#include <QCoreApplication>
#include <QDataStream>
#include <QDebug>
#include <QUrl>
#include <QSettings>
#include <QVariant>
class MusicOwner
{
public:
MusicOwner() :
songs_count(0),
id(0)
{}
private:
friend QDataStream &operator <<(QDataStream &stream, const MusicOwner &val);
friend QDataStream &operator >>(QDataStream &stream, MusicOwner &val);
friend QDebug operator<< (QDebug d, const MusicOwner &owner);
public:
int songs_count;
int id;
QString name;
QString screen_name;
QUrl photo;
};
QDataStream &operator <<(QDataStream &stream, const MusicOwner &val)
{
stream << val.id;
stream << val.name;
stream << val.songs_count;
stream << val.screen_name;
return stream;
}
QDataStream &operator >>(QDataStream &stream, MusicOwner &val)
{
stream >> val.id;
stream >> val.name;
stream >> val.songs_count;
stream >> val.screen_name;
return stream;
}
QDebug operator <<(QDebug d, const MusicOwner &owner)
{
d << "MusicOwner("
<< owner.id << ","
<< owner.name << ","
<< owner.songs_count << ","
<< owner.screen_name << ")";
return d;
}
Q_DECLARE_METATYPE(MusicOwner)
const QString kSettingGroup = "Group";
void Save() {
QSettings s;
s.beginGroup(kSettingGroup);
s.beginWriteArray("bookmarks");
int index = 0;
for (int i = 0; i < 100; ++i){
if (random() % 5 == 0) {
s.setArrayIndex(index);
MusicOwner owner;
owner.id = i;
owner.name ="Hello world";
owner.songs_count = i * 2;
owner.screen_name = "hello_world";
s.setValue("owner", QVariant::fromValue(owner));
qDebug() << "Saved" << i << ":" << owner;
++index;
}
}
s.endArray();
qDebug() << "Saved" << index << "elements";
}
void Load() {
QSettings s;
s.beginGroup(kSettingGroup);
int max = s.beginReadArray("bookmarks");
qDebug() << "To load" << max << "elements";
for (int i = 0; i < max; ++i){
s.setArrayIndex(i);
MusicOwner owner = s.value("owner").value<MusicOwner>();
qDebug() << "\tLoaded" << i << ":" << owner;
}
s.endArray();
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
qRegisterMetaTypeStreamOperators<MusicOwner>("MusicOwner");
QSettings s;
Load();
Save();
return a.exec();
}
也许您可以在此变体中发现使用 QSettings 的不同之处?