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

Popular posts from this blog

jquery - How can I dynamically add a browser tab? -

node.js - Getting the socket id,user id pair of a logged in user(s) -

keyboard - C++ GetAsyncKeyState alternative -