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. saving a custom Unit* class
Qt 6.11 is out! See what's new in the release blog

saving a custom Unit* class

Scheduled Pinned Locked Moved Unsolved General and Desktop
12 Posts 3 Posters 6.0k 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.
  • SGaistS Offline
    SGaistS Offline
    SGaist
    Lifetime Qt Champion
    wrote on last edited by
    #2

    Hi,

    Did you also implement the stream operators ?

    Note that there's something wrong going on here. You have implement a copy operator for your QObject based class which wrong. QObject is note a copyable class, see here for more information.

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

    1 Reply Last reply
    0
    • A Offline
      A Offline
      AndreAhmed
      wrote on last edited by
      #3

      I implemented the stream operators >> and << and still I can't save the qobject pointer into the file settings. I don't know why. what else do you need to dig for the problem ?

      and thanks for the note

      1 Reply Last reply
      0
      • SGaistS Offline
        SGaistS Offline
        SGaist
        Lifetime Qt Champion
        wrote on last edited by
        #4

        Can you share your operators implementation ?

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

        1 Reply Last reply
        0
        • A Offline
          A Offline
          AndreAhmed
          wrote on last edited by
          #5

          why I can't save a pointer qproperty like Unit*.
          that's what the error says
          QVariant::save: unable to save type 'Unit*'

          1 Reply Last reply
          0
          • SGaistS Offline
            SGaistS Offline
            SGaist
            Lifetime Qt Champion
            wrote on last edited by
            #6

            I don't know since you didn't share the complete code. Anyway, here is a dummy implementation that shows how it works:

            class MyObject : public QObject
            {
            public:
                MyObject(QObject *parent = 0)
                    : QObject(parent)
                {}
            
                QString foo() const { return _foo; }
                void setFoo(const QString& foo) {
                    _foo = foo;
                }
            
            private:
                QString _foo;
            };
            
            QDataStream &operator<<(QDataStream &ds, MyObject *object)
            {
                ds << object->foo();
                return ds;
            }
            
            QDataStream &operator>>(QDataStream &ds, MyObject *object)
            {
                QString foo;
                ds >> foo;
                object->setFoo(foo);
                return ds;
            }
            
            QDebug operator<<(QDebug dbg, MyObject *object)
            {
                dbg << object->metaObject()->className() << object->foo();
                return dbg;
            }
            
            Q_DECLARE_METATYPE(MyObject *)
            
            int main(int argc, char *argv[])
            {
                QApplication app(argc, argv);
                qRegisterMetaType<MyObject *>();
                qRegisterMetaTypeStreamOperators<MyObject *>();
                MyObject *object = new MyObject;
                object->setFoo("myfoo");
            
                QBuffer buffer;
                buffer.open(QBuffer::WriteOnly);
                QDataStream ds(&buffer);
                ds << object;
                buffer.close();
            
                // later
                buffer.open(QBuffer::ReadOnly);
                ds.setDevice(&buffer);
                MyObject *object2 = new MyObject;
                ds >> object2;
            
                qDebug() << object2;
                delete object;
                delete object2;
                return 0;
            }
            

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

            1 Reply Last reply
            1
            • A Offline
              A Offline
              AndreAhmed
              wrote on last edited by
              #7

              I'm trying to define the operators >> and << for a custom class called Unit, and I need to store a pointer.

              here is how I define the functions

              QDataStream &operator<<(QDataStream &out, const Unit *unit)
              {
              out << unit->value();
              return out;
              }

              QDataStream &operator>>(QDataStream &in, Unit *unit)
              {
              double value;
              in >> value;
              unit->setUserValue(value);
              return in;
              }

              void Unit::setUserValue(const qreal userValue)
              {
              qDebug() << "setUserValue" << this->userValue() << userValue << QString::number(m_unit,2);
              if (this->userValue() == userValue)
              return;

              if(isDefault())
                  m_value = userValue;
              else
                  m_value = UnitManager::convertFrom(userValue,m_unit);
              
              qDebug() << "Value" <<  m_value;
              
              emit userValueChanged();
              setDirty(RamDirty);
              

              }

              qRegisterMetaType<Unit*>();
              qRegisterMetaTypeStreamOperators<Unit *>();
              I'm getting the following compilation error message

              error: no match for 'operator>>' (operand types are 'QDataStream' and 'Unit*')
              and also an error here

              /usr/include/qt/QtCore/qmetatype.h:771: error: invalid initialization of non-const reference of type 'quint8& {aka unsigned char&}' from an rvalue of type 'quint8 {aka unsigned char}'
              stream >> static_cast<T>(t);
              ^
              I also defined the meta type

              Q_DECLARE_METATYPE(Unit)
              Q_DECLARE_METATYPE(Unit*)

              1 Reply Last reply
              0
              • SGaistS Offline
                SGaistS Offline
                SGaist
                Lifetime Qt Champion
                wrote on last edited by
                #8

                Unit is a QObject base class you shouldn't call Q_DECLARE_METATYPE on it.

                Where are you doing the declaration and registrations ?

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

                1 Reply Last reply
                0
                • A Offline
                  A Offline
                  AndreAhmed
                  wrote on last edited by
                  #9

                  I'm doing it in main()

                  1 Reply Last reply
                  0
                  • SGaistS Offline
                    SGaistS Offline
                    SGaist
                    Lifetime Qt Champion
                    wrote on last edited by
                    #10

                    Something's wrong with your streaming operations, you don't save and load the same formats you use for your class. You have qreal on one side then double on another side.

                    You should really be precise when doing such operations.

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

                    1 Reply Last reply
                    0
                    • A Offline
                      A Offline
                      AndreAhmed
                      wrote on last edited by
                      #11

                      I'm still getting the following error

                      /usr/include/qt/QtCore/qmetatype.h:771: error: no match for 'operator>>' (operand types are 'QDataStream' and 'Unit')
                               stream >> *static_cast<T*>(t);
                                      ^
                      
                      
                      QDataStream &operator<<(QDataStream &out, const Unit *&unit)
                      {
                         out << unit->value();
                         return out;
                      }
                      
                      QDataStream &operator>>(QDataStream &in, Unit *&unit)
                      {
                         qreal value;
                         in >> value;
                         unit->setUserValue(value);
                         return in;
                      }
                      

                      In MAIN I define

                      qRegisterMetaType<Unit*>();
                      qRegisterMetaTypeStreamOperators<Unit *>();
                      
                      ```in the header of Unit.h I define
                      

                      Q_DECLARE_METATYPE(Unit*)
                      Q_DECLARE_METATYPE(Unit)

                      kshegunovK 1 Reply Last reply
                      0
                      • A AndreAhmed

                        I'm still getting the following error

                        /usr/include/qt/QtCore/qmetatype.h:771: error: no match for 'operator>>' (operand types are 'QDataStream' and 'Unit')
                                 stream >> *static_cast<T*>(t);
                                        ^
                        
                        
                        QDataStream &operator<<(QDataStream &out, const Unit *&unit)
                        {
                           out << unit->value();
                           return out;
                        }
                        
                        QDataStream &operator>>(QDataStream &in, Unit *&unit)
                        {
                           qreal value;
                           in >> value;
                           unit->setUserValue(value);
                           return in;
                        }
                        

                        In MAIN I define

                        qRegisterMetaType<Unit*>();
                        qRegisterMetaTypeStreamOperators<Unit *>();
                        
                        ```in the header of Unit.h I define
                        

                        Q_DECLARE_METATYPE(Unit*)
                        Q_DECLARE_METATYPE(Unit)

                        kshegunovK Offline
                        kshegunovK Offline
                        kshegunov
                        Moderators
                        wrote on last edited by
                        #12

                        @AndreAhmed said:

                        /usr/include/qt/QtCore/qmetatype.h:771: error: no match for 'operator>>' (operand types are 'QDataStream' and 'Unit')
                        stream >> static_cast<T>(t);

                        Follow the compiler's error description! You're trying to save an instance of the class (i.e. an object), then you provide operators for saving a pointer to that class ... the compiler can't match one to the other.

                        QDataStream &operator>>(QDataStream &out, Unit *&unit)
                        

                        is quite different from:

                        QDataStream &operator>>(QDataStream &out, Unit &unit)  //< This is what you're invoking with stream >> *static_cast<Unit*>(t);
                        

                        Additionally, don't pass pointer references, unless you intend on changing them ... this could have unforeseen consequences if in the implementation you do something along the lines of:

                        unit = nullptr;
                        

                        for example.

                        Best is to even make a further step (although it's often considered quite over-protective) and make sure the pointer will not be moved, not only that it's pointing to a const object:

                        QDataStream &operator<<(QDataStream &out, const Unit * const unit) //< Forbid moving the pointer inside the implementation, not only modifying the object
                        {
                        }
                        
                        QDataStream & operator >> (QDataStream & in, Unit * const unit) //< Again, the pointer is constant, can't be modified, the object is not though
                        {
                        }
                        

                        Read and abide by the Qt Code of Conduct

                        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