Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. Serialize nested user defined class in Q_PROPERTY
Forum Updated to NodeBB v4.3 + New Features

Serialize nested user defined class in Q_PROPERTY

Scheduled Pinned Locked Moved Unsolved QML and Qt Quick
5 Posts 3 Posters 1.8k Views 2 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • E Offline
    E Offline
    EagleNN
    wrote on 1 Feb 2017, 18:46 last edited by
    #1

    I faced with following problem: I can't serialize user defined object from Q_PROPERTY
    I try to serialize RegistersSettings class to QDataStream. The idea is to be able to serialize it to text file (using << operator) and later be able to read it (using >> operator). It should verify that fields that was readed from file are still valid. So I inspect property for that.
    The issue is that Q_PROPERTY(QList<RegisterGroupSettings> groups MEMBER groups) is not work as expected.
    It looks like it's possible to create such functionality, but it looks that it's not so easy.
    Could anyone help with the common way how to serialize user defined class from Q_PROPERTY?

    The code is simplifyed to be more readable, but the main idea is in place.

    class RegisterGroupSettings:SettingsItem<RegisterGroupSettings>
    {
    private:
        Q_GADGET
        Q_PROPERTY(QString name MEMBER name)
        Q_PROPERTY(int interval MEMBER interval)
    
    public:
        QString name;
        int     interval;
    };
    Q_DECLARE_METATYPE(RegisterGroupSettings)
    
    class RegistersSettings:SettingsItem<RegistersSettings>
    {
    private:
        Q_GADGET
        Q_PROPERTY(QList<RegisterGroupSettings> groups MEMBER groups)
        Q_PROPERTY(int code MEMBER code)
    
    public:
        QList<RegisterGroupSettings> groups;
        int code;
    };
    Q_DECLARE_METATYPE(RegistersSettings)
    

    SettingsItem is a helper fo unification

    template <typename T> class SettingsItem
    {
    public:
        friend QDataStream & operator << (QDataStream &arch, const T & object)
        {
            const QMetaObject &mo = object.staticMetaObject;
            int cnt = mo.propertyCount();
            QString prop_name;
            QVariant prop_value;
            arch << cnt;
            while (cnt>0)
            {
                prop_name = mo.property(cnt-1).name();
                prop_value = mo.property(cnt-1).readOnGadget(&object);
                arch << prop_name;
                arch << prop_value;
                cnt--;
            }
            return arch;
        }
    
        friend QDataStream & operator >> (QDataStream &arch, T & object)
        {
            const QMetaObject &mo = object.staticMetaObject;
            int cnt=0;
            QString prop_name;
            QVariant prop_value;
            int prop_index;
            arch >> cnt;
            while (cnt>0)
            {
                arch >> prop_name;
                arch >> prop_value;
                prop_index = mo.indexOfProperty(prop_name.toStdString().c_str());
                if (prop_index > -1)
                {
                    mo.property(prop_index).writeOnGadget(&object, prop_value);
                }
                cnt--;
            }
            return arch;
        }
    
        friend bool operator == (const T &first, const T &second)
        {
            const QMetaObject &mo = first.staticMetaObject;
            int cnt = mo.propertyCount();
            QString prop_name;
            QVariant oProp_value;
            QVariant dProp_value;
            while (cnt>0)
            {
                prop_name = mo.property(cnt-1).name();
                oProp_value = mo.property(cnt-1).readOnGadget(&first);
                dProp_value = mo.property(cnt-1).readOnGadget(&second);
                if (oProp_value == dProp_value)
                {
                    cnt--;
                    continue;
                }
                return false;
            }
    
            return true;
        }
    
        friend bool operator != (const T &first, const T &second)
        {
            return !( first == second );
        }
    };
    
    K 1 Reply Last reply 1 Feb 2017, 19:40
    0
    • E EagleNN
      1 Feb 2017, 18:46

      I faced with following problem: I can't serialize user defined object from Q_PROPERTY
      I try to serialize RegistersSettings class to QDataStream. The idea is to be able to serialize it to text file (using << operator) and later be able to read it (using >> operator). It should verify that fields that was readed from file are still valid. So I inspect property for that.
      The issue is that Q_PROPERTY(QList<RegisterGroupSettings> groups MEMBER groups) is not work as expected.
      It looks like it's possible to create such functionality, but it looks that it's not so easy.
      Could anyone help with the common way how to serialize user defined class from Q_PROPERTY?

      The code is simplifyed to be more readable, but the main idea is in place.

      class RegisterGroupSettings:SettingsItem<RegisterGroupSettings>
      {
      private:
          Q_GADGET
          Q_PROPERTY(QString name MEMBER name)
          Q_PROPERTY(int interval MEMBER interval)
      
      public:
          QString name;
          int     interval;
      };
      Q_DECLARE_METATYPE(RegisterGroupSettings)
      
      class RegistersSettings:SettingsItem<RegistersSettings>
      {
      private:
          Q_GADGET
          Q_PROPERTY(QList<RegisterGroupSettings> groups MEMBER groups)
          Q_PROPERTY(int code MEMBER code)
      
      public:
          QList<RegisterGroupSettings> groups;
          int code;
      };
      Q_DECLARE_METATYPE(RegistersSettings)
      

      SettingsItem is a helper fo unification

      template <typename T> class SettingsItem
      {
      public:
          friend QDataStream & operator << (QDataStream &arch, const T & object)
          {
              const QMetaObject &mo = object.staticMetaObject;
              int cnt = mo.propertyCount();
              QString prop_name;
              QVariant prop_value;
              arch << cnt;
              while (cnt>0)
              {
                  prop_name = mo.property(cnt-1).name();
                  prop_value = mo.property(cnt-1).readOnGadget(&object);
                  arch << prop_name;
                  arch << prop_value;
                  cnt--;
              }
              return arch;
          }
      
          friend QDataStream & operator >> (QDataStream &arch, T & object)
          {
              const QMetaObject &mo = object.staticMetaObject;
              int cnt=0;
              QString prop_name;
              QVariant prop_value;
              int prop_index;
              arch >> cnt;
              while (cnt>0)
              {
                  arch >> prop_name;
                  arch >> prop_value;
                  prop_index = mo.indexOfProperty(prop_name.toStdString().c_str());
                  if (prop_index > -1)
                  {
                      mo.property(prop_index).writeOnGadget(&object, prop_value);
                  }
                  cnt--;
              }
              return arch;
          }
      
          friend bool operator == (const T &first, const T &second)
          {
              const QMetaObject &mo = first.staticMetaObject;
              int cnt = mo.propertyCount();
              QString prop_name;
              QVariant oProp_value;
              QVariant dProp_value;
              while (cnt>0)
              {
                  prop_name = mo.property(cnt-1).name();
                  oProp_value = mo.property(cnt-1).readOnGadget(&first);
                  dProp_value = mo.property(cnt-1).readOnGadget(&second);
                  if (oProp_value == dProp_value)
                  {
                      cnt--;
                      continue;
                  }
                  return false;
              }
      
              return true;
          }
      
          friend bool operator != (const T &first, const T &second)
          {
              return !( first == second );
          }
      };
      
      K Offline
      K Offline
      kshegunov
      Moderators
      wrote on 1 Feb 2017, 19:40 last edited by kshegunov 2 Jan 2017, 19:58
      #2

      @EagleNN said in Serialize nested user defined class in Q_PROPERTY:

      The issue is that Q_PROPERTY(QList<RegisterGroupSettings> groups MEMBER groups) is not work as expected.

      You need t declare the list specialization as a metatype, provide stream operators for it, and finally register that stream operators with the meta-type system. Qt doesn't know about your specialization of that template class and without these things so it can't put it into a QVariant, neither can it write it to the data stream, nor can it be read from the stream.

      PS.
      Also I advise you use proper static access for static members, i.e.: T::staticMetaObject.

      Read and abide by the Qt Code of Conduct

      E 1 Reply Last reply 1 Feb 2017, 21:05
      2
      • K kshegunov
        1 Feb 2017, 19:40

        @EagleNN said in Serialize nested user defined class in Q_PROPERTY:

        The issue is that Q_PROPERTY(QList<RegisterGroupSettings> groups MEMBER groups) is not work as expected.

        You need t declare the list specialization as a metatype, provide stream operators for it, and finally register that stream operators with the meta-type system. Qt doesn't know about your specialization of that template class and without these things so it can't put it into a QVariant, neither can it write it to the data stream, nor can it be read from the stream.

        PS.
        Also I advise you use proper static access for static members, i.e.: T::staticMetaObject.

        E Offline
        E Offline
        EagleNN
        wrote on 1 Feb 2017, 21:05 last edited by
        #3

        @kshegunov said in Serialize nested user defined class in Q_PROPERTY:

        You need t declare the list specialization as a metatype,

        RegisterGroupSettings is declared as metatype (Q_DECLARE_METATYPE(RegisterGroupSettings))

        provide stream operators for it,

        Stream operators << and >> provided from template class SettingsItem

        and finally register that stream operators with the meta-type system.

        So class RegistersSettings should be extended with constructor?

            RegistersSettings()
            {
                qRegisterMetaTypeStreamOperators<RegisterGroupSettings>("RegisterGroupSettings");
                qRegisterMetaTypeStreamOperators<QList<RegisterGroupSettings>>("QList<RegisterGroupSettings>");
            }
        
        1 Reply Last reply
        0
        • SGaistS Offline
          SGaistS Offline
          SGaist
          Lifetime Qt Champion
          wrote on 1 Feb 2017, 21:24 last edited by
          #4

          What error are you getting exactly ?

          Interested in AI ? www.idiap.ch
          Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

          E 1 Reply Last reply 2 Feb 2017, 16:05
          0
          • SGaistS SGaist
            1 Feb 2017, 21:24

            What error are you getting exactly ?

            E Offline
            E Offline
            EagleNN
            wrote on 2 Feb 2017, 16:05 last edited by
            #5

            The solution is to extend template with constructor

                SettingsItem()
                {
                    qRegisterMetaType<T>();
                    qRegisterMetaTypeStreamOperators<T>(T::staticMetaObject.className());
                }
            

            and register nested type in class constructor

                RegistersSettings()
                {
                    qRegisterMetaTypeStreamOperators<QList<RegisterGroupSettings>>("QList<RegisterGroupSettings>");
                }
            
            1 Reply Last reply
            0

            1/5

            1 Feb 2017, 18:46

            • Login

            • Login or register to search.
            1 out of 5
            • First post
              1/5
              Last post
            0
            • Categories
            • Recent
            • Tags
            • Popular
            • Users
            • Groups
            • Search
            • Get Qt Extensions
            • Unsolved