Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QDatastream deserialze Q_PROPERTY signal change
Forum Updated to NodeBB v4.3 + New Features

QDatastream deserialze Q_PROPERTY signal change

Scheduled Pinned Locked Moved Solved General and Desktop
6 Posts 2 Posters 448 Views 1 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.
  • S Offline
    S Offline
    Shazter
    wrote on last edited by
    #1

    Hello, I'm receiving data by ethernet (TCP) and I would like to parse the datastream into my dataclass which shall be populated to qml. I would like to get notified, after a change of the value.

    class student : public QObject
    {
        Q_OBJECT // Q_OBJECT macro will take care of generating proper metaObject for your class
        Q_PROPERTY(int id READ getId WRITE setId)
        Q_PROPERTY(QString Name READ getName WRITE setName)
    public:
        student();
        int getId() const { return id; }
        void setId(int newId) { id = newId; }
        QString getName() const { return Name; }
        void setName(const QString &newName) { Name = newName; }
    
    private:
        int id;
        QString Name;
    };
    

    If I deserialze my QByteArray by QDatastream into the private member, then I don't get the notification, because I don't use my setter.

    // no notification about propertychange
    QByteArray ba; // mydata inside
    QDataStream in (&ba,QIODevice::ReadWrite)
    
    in << m_id << m_name;
    

    This seems not to be allowed:

    QByteArray ba; // mydata inside
    QDataStream in (&ba,QIODevice::ReadWrite)
    
    in << set_Id(m_id) << set_Name (m_name); // not allowed?!
    
    

    Question:

    1. How I can get my notification about the change?
    2. Do you recommend different approche to deserialze to my dataclass?
    Gojir4G 2 Replies Last reply
    0
    • S Shazter

      Hello, I'm receiving data by ethernet (TCP) and I would like to parse the datastream into my dataclass which shall be populated to qml. I would like to get notified, after a change of the value.

      class student : public QObject
      {
          Q_OBJECT // Q_OBJECT macro will take care of generating proper metaObject for your class
          Q_PROPERTY(int id READ getId WRITE setId)
          Q_PROPERTY(QString Name READ getName WRITE setName)
      public:
          student();
          int getId() const { return id; }
          void setId(int newId) { id = newId; }
          QString getName() const { return Name; }
          void setName(const QString &newName) { Name = newName; }
      
      private:
          int id;
          QString Name;
      };
      

      If I deserialze my QByteArray by QDatastream into the private member, then I don't get the notification, because I don't use my setter.

      // no notification about propertychange
      QByteArray ba; // mydata inside
      QDataStream in (&ba,QIODevice::ReadWrite)
      
      in << m_id << m_name;
      

      This seems not to be allowed:

      QByteArray ba; // mydata inside
      QDataStream in (&ba,QIODevice::ReadWrite)
      
      in << set_Id(m_id) << set_Name (m_name); // not allowed?!
      
      

      Question:

      1. How I can get my notification about the change?
      2. Do you recommend different approche to deserialze to my dataclass?
      Gojir4G Offline
      Gojir4G Offline
      Gojir4
      wrote on last edited by Gojir4
      #2

      @shazter Hi,

      To get notification, you need to specify and define signals for properties changes.

      class student : public QObject
      { 
          Q_OBJECT
          Q_PROPERTY(int id READ getId WRITE setId NOTIFY idChanged)
          Q_PROPERTY(QString Name READ getName WRITE setName NOTIFY nameChanged)
      
      ...
      signals: 
          void idChanged(int id);
          void nameChanged(const QString &name);
      ...
      };
      

      Then you need to update your setters to call the signal when a modification occurs:

      void setId(int newId) { 
          if(id == newId) return;
          id = newId; 
          emit idChanged(newId);
      }
      void setName(const QString &newName) { 
          if(Name == newName) return;
          Name = newName; 
          emit nameChanged(newName);
      }
      

      Note you can also remove the actual setters and generate them automatically from Qt Creator. In my case I'm using ALT + RETURN shortcut (Windows) on the line where Q_PROPERTY is defined and it shows a menu "add missing members" which generates member variable, getter, setter and signal of the property.

      About deserializing, I think it should be something like:

      // no notification about propertychange
      QByteArray ba; // mydata inside
      QDataStream in (&ba)
      
      QString id;
      QString name;
      in >> id >> name;
      setId(id);
      setName(name);
      
      1 Reply Last reply
      1
      • S Shazter

        Hello, I'm receiving data by ethernet (TCP) and I would like to parse the datastream into my dataclass which shall be populated to qml. I would like to get notified, after a change of the value.

        class student : public QObject
        {
            Q_OBJECT // Q_OBJECT macro will take care of generating proper metaObject for your class
            Q_PROPERTY(int id READ getId WRITE setId)
            Q_PROPERTY(QString Name READ getName WRITE setName)
        public:
            student();
            int getId() const { return id; }
            void setId(int newId) { id = newId; }
            QString getName() const { return Name; }
            void setName(const QString &newName) { Name = newName; }
        
        private:
            int id;
            QString Name;
        };
        

        If I deserialze my QByteArray by QDatastream into the private member, then I don't get the notification, because I don't use my setter.

        // no notification about propertychange
        QByteArray ba; // mydata inside
        QDataStream in (&ba,QIODevice::ReadWrite)
        
        in << m_id << m_name;
        

        This seems not to be allowed:

        QByteArray ba; // mydata inside
        QDataStream in (&ba,QIODevice::ReadWrite)
        
        in << set_Id(m_id) << set_Name (m_name); // not allowed?!
        
        

        Question:

        1. How I can get my notification about the change?
        2. Do you recommend different approche to deserialze to my dataclass?
        Gojir4G Offline
        Gojir4G Offline
        Gojir4
        wrote on last edited by
        #3

        @shazter Just another remarks about naming conventions. I suggest that you use Uppercase first for naming your classes, and also using m_or m prefix for your member variables to avoid confusions.
        In the class student, there is one property name id which starts with lowercase character, and the other one Name with uppercase character. I think this is very confusing.

        For exemple, I would rename class student to Student, id to m_id and Name to m_name

        That's not really critical but when you have tens of classes or variables it makes everything more clear.

        1 Reply Last reply
        1
        • S Offline
          S Offline
          Shazter
          wrote on last edited by
          #4

          Many thanks for your example and advice this helps me alot.

          Oh sorry forgot to add the signals and of course the my Q_PROPERTY example was wrong.

          QString id;
          QString name;
          in >> id >> name;
          setId(id);
          setName(name);
          

          I hoped to avoid so much boiler code and additional temporary variables, because one message frame can be maxsize ~64kByte, but looks like their is no better solution to get the notification update.

          1 Reply Last reply
          0
          • S Offline
            S Offline
            Shazter
            wrote on last edited by
            #5

            I forgot to ask one more question to the same topic.

            When I updated my private members by Q_PROPERTY setter in QML the UI will show the values immanently , then members will serialized to QDatastream, and then send to tcp-client. The client shall confirm data was a received and CRC check was successful too, means no problem with shown values in UI both are consistent. If the received data is for some reason partly corrupted, then client will send again frame with current valid data, then I started the deserialze again and settings the dataclass again to show the correct values.

            Is this understanding correct?

            Or shall I show all old values until the client has confirmed received data and then emit a signal for each member value by using the setter?

            Gojir4G 1 Reply Last reply
            0
            • S Shazter

              I forgot to ask one more question to the same topic.

              When I updated my private members by Q_PROPERTY setter in QML the UI will show the values immanently , then members will serialized to QDatastream, and then send to tcp-client. The client shall confirm data was a received and CRC check was successful too, means no problem with shown values in UI both are consistent. If the received data is for some reason partly corrupted, then client will send again frame with current valid data, then I started the deserialze again and settings the dataclass again to show the correct values.

              Is this understanding correct?

              Or shall I show all old values until the client has confirmed received data and then emit a signal for each member value by using the setter?

              Gojir4G Offline
              Gojir4G Offline
              Gojir4
              wrote on last edited by
              #6

              @shazter The way you manage errors are IMHO depending of the context of the application and how you want it to behave. I don't think a method is better than another.

              1 Reply Last reply
              0

              • Login

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