c++ - Read array of custom metatype from QSettings -
i have problem reading custom metatype data qsetting. have class:
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)
with overloaded:
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; }
and somewhere @ program's start call:
qregistermetatypestreamoperators<musicowner>("musicowner");
to read , write use 2 functions: saving works fine, data saving appearing in settings file.
void vkservice::savebookmarks() { trace; qsettings s; s.begingroup(ksettinggroup); s.beginwritearray("bookmarks"); int index = 0; (int = 0; < 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(); }
problems function, it's load count correctly, it's loading empty default constructed items.
void vkservice::loadbookmarks() { qsettings s; s.begingroup(ksettinggroup); int max = s.beginreadarray("bookmarks"); (int = 0; < max; ++i){ s.setarrayindex(i); musicowner owner = s.value("owner").value<musicowner>(); qlog(info) << "load" << << ":" << owner; appendbookmarkfromradio(root_item_, owner.toownerradio()); } s.endarray(); }
i rewrote new project testing, works fine. spend 2 hour find out, why variant reading data correctly first variant not. owner in first variant converting correctly. data in settings file in both variants same.
#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; (int = 0; < 100; ++i){ if (random() % 5 == 0) { s.setarrayindex(index); musicowner owner; owner.id = i; owner.name ="hello world"; owner.songs_count = * 2; owner.screen_name = "hello_world"; s.setvalue("owner", qvariant::fromvalue(owner)); qdebug() << "saved" << << ":" << 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"; (int = 0; < max; ++i){ s.setarrayindex(i); musicowner owner = s.value("owner").value<musicowner>(); qdebug() << "\tloaded" << << ":" << owner; } s.endarray(); } int main(int argc, char *argv[]) { qcoreapplication a(argc, argv); qregistermetatypestreamoperators<musicowner>("musicowner"); qsettings s; load(); save(); return a.exec(); }
maybe can find difference in work qsettings in variants?
you not careful @ namespaces in example. can't make "minimal case" doesn't use namespaces if do, in fact, use them in non-working code.
the following compileable example uses namespaces , works fine in both qt 4.8 , 5.1. note settings not portable default between 4.8 , 5.1, don't know if that's bug or feature.
#include <qcoreapplication> #include <qdatastream> #include <qdebug> #include <qsettings> #include <qvariant> namespace vkservice { class musicownera { friend qdatastream &operator <<(qdatastream &stream, const musicownera &val); friend qdatastream &operator >>(qdatastream &stream, musicownera &val); friend qdebug operator<< (qdebug d, const musicownera &owner); public: musicownera() : id(0) {} int id; qstring name; }; qdatastream &operator <<(qdatastream &stream, const vkservice::musicownera &val) { stream << val.id; stream << val.name; return stream; } qdatastream &operator >>(qdatastream &stream, vkservice::musicownera &val) { stream >> val.id; stream >> val.name; return stream; } qdebug operator <<(qdebug d, const vkservice::musicownera &owner) { d << "vkservice::musicownera(" << owner.id << "," << owner.name << ")"; return d; } } q_declare_metatype(vkservice::musicownera) void save() { qsettings s; s.beginwritearray("bookmarks"); int index = 0; (int = 0; < 100; ++i){ if (random() % 5 == 0) { s.setarrayindex(index); vkservice::musicownera owner; owner.id = i; owner.name ="hello world"; s.setvalue("owner", qvariant::fromvalue(owner)); qdebug() << "saved" << << ":" << owner; ++index; } } s.endarray(); qdebug() << "saved" << index << "elements"; } void load() { qsettings s; int max = s.beginreadarray("bookmarks"); qdebug() << "to load" << max << "elements"; (int = 0; < max; ++i){ s.setarrayindex(i); vkservice::musicownera owner = s.value("owner").value<vkservice::musicownera>(); qdebug() << "\tloaded" << << ":" << owner; } s.endarray(); } int main(int argc, char **argv) { qcoreapplication a(argc, argv); a.setorganizationdomain("16549302.stackoverflow.com"); qregistermetatypestreamoperators<vkservice::musicownera>("vkservice::musicownera"); load(); save(); }
Comments
Post a Comment