Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Serialization Example



  • I am trying to serialize my class but I cannot find an example. I tried the code below, but I get that it does not define a type.

    #include <QObject>
    #include <QDataStream>
    #include <QRectF>
    #include <QLineF>
    #include <QDebug>
    
    class MyClass : public QObject
    {
        Q_OBJECT
    public:
        explicit MyClass(QObject *parent = nullptr);
    
        QDataStream &MyClass;::operator <<(QDataStream &out, const MyClass &mc){
            out << mc.br << mc.ln;
            return out;
    
        }
        QDataStream &MyClass;::operator >>(QDataStream &in, const MyClass &mc){
            in >> mc.br >> mc.ln;
            return in;
        }
        QRectF br;
        QLineF ln;
    
    signals:
    
    public slots:
    };
    

  • Lifetime Qt Champion

    Hi,

    Declare the stream operators in the same file but outside of your class and implement them in the implementation file from your class.

    By the way, you have a semicolon between MyClass and the two colon.



  • @SGaist As for the semicolon, that came from an example "http://www.bogotobogo.com/Qt/Qt5_QFile_Serialization_Class.php".

    class MyClass : public QObject
    {
        Q_OBJECT
    public:
        explicit MyClass(QObject *parent = nullptr);
    
    
        QRectF br;
        QLineF ln;
    
    signals:
    
    public slots:
    };
    QDataStream &MyClass;::operator <<(QDataStream &out, const MyClass &mc){
        out << mc.br << mc.ln;
        return out;
    
    }
    QDataStream &MyClass;::operator >>(QDataStream &in, const MyClass &mc){
        in >> mc.br >> mc.ln;
        return in;
    }
    

    That did not work.



  • @ofmrew Forgot to remove the semicolons. With them removed I get:

    /home/xxx/SerializationExperiments/myclass.h:24: error: ‘QDataStream& MyClass::operator<<(QDataStream&, const MyClass&)’ must take exactly one argument
     QDataStream &MyClass::operator <<(QDataStream &out, const MyClass &mc){
                                                                          ^
    

  • Lifetime Qt Champion

    That's a typo, remove it.

    By the way, the operator>> takes a reference, not a const reference. Otherwise you won't be able to update the content of the object you pass.



  • @SGaist

    QDataStream &MyClass::operator <<(QDataStream &out, MyClass &mc){
        out << mc.br << mc.ln;
        return out;
    
    }
    QDataStream &MyClass::operator >>(QDataStream &in, MyClass &mc){
        in >> mc.br >> mc.ln;
        return in;
    }
    
    /home/xxx/SerializationExperiments/myclass.h:24: error: ‘QDataStream& MyClass::operator<<(QDataStream&, MyClass&)’ must take exactly one argument
     QDataStream &MyClass::operator <<(QDataStream &out, MyClass &mc){
                                                                    ^
    

    It dtill complains about more than one argument. How do I fix that?


  • Lifetime Qt Champion

    Remove MyClass;:: from the declaration.

    It's shown in the Reading And Writing Other Qt Classes part of QDataStream's documentation.



  • @SGaist Did the "http://www.bogotobogo.com/Qt/Qt5_QFile_Serialization_Class.php" ever work? That is the only example I could find to use as a model.

    QDataStream &operator <<(QDataStream &out, MyClass &mc);

    Compiles, but do I need to put the implementation in the cpp file? If so, what is the format?


  • Lifetime Qt Champion

    Copy the methods as they are in the implementation file and just leave the declaration in the header.



  • @SGaist That compiled. Not to testing. Thanks.



  • @ofmrew The status after the write to datastream is 0, but the >> does not appear to work. I added MyClass to a vector and tried to serialize it, but it failed to return the vector from the stream. A breakpoint, in MyClass, on << is activated, but one on >> is not.

    class MyCanvas : public QWidget
    {
        Q_OBJECT
    public:
        explicit MyCanvas(QWidget *parent = nullptr);
    
        void create();
        void store();
        void load();
    
        QVector<MyClass> cell;
        QDataStream stream;
    
    
    MyCanvas::MyCanvas(QWidget *parent) : QWidget(parent)
    {
    
    }
    
    void MyCanvas::create()
    {
    //    QVector<MyClass>cell;
    
        MyClass line1(QRectF(50.0, 50.0, 200.0, 200.0), QLineF(50.0, 50.0, 250.0, 250.0));
        cell.append(line1);
        MyClass line2(QRectF(250.0, 50.0, 200.0, 200.0), QLineF(250.0, 250.0, 500.0, 50.0));
        cell.append(line2);
    }
    
    void MyCanvas::store()
    {
    //    stream = new QDataStream();
        stream<<cell;
        qDebug() << "status" << stream.status();
    //    qDebug() << stream;
    }
    
    void MyCanvas::load()
    {
    //    cell2 = new QVector<MyClass>();
        cell.clear();
        stream>>cell;
        qDebug() << cell.size();
    //    qDebug() << cell;
    }
    class MyClass
    {
    public:
        explicit MyClass();
        MyClass(QRectF r, QLineF l);
        void addBoundingRect(QRectF);
        void addLine(QLineF);
    
    
        QRectF br;
        QLineF ln;
    
    signals:
    
    public slots:
    };
    QDataStream &operator <<(QDataStream &out, const MyClass &mc);
    QDataStream &operator >>(QDataStream &in, MyClass &mc);
    
    MyClass::MyClass() {}
    MyClass::MyClass(QRectF r, QLineF l) : br{r}, ln{l}
    {
    
    }
    
    void MyClass::addBoundingRect(QRectF r)
    {
        br = r;
    }
    QDataStream &operator <<(QDataStream &out, const MyClass &mc){
        out << mc.br << mc.ln;
        return out;
    
    }
    QDataStream &operator >>(QDataStream &in, MyClass &mc){
        in >> mc.br >> mc.ln;
        return in;
    }
    
    ```Is it failing to create MyClass?


  • @ofmrew Ignore the last post: Like an idiot I missed the fact that QDataStream is a file. Thanks for the help.



  • @ofmrew I tested the serialization both out and in. Now I am trying to serialize QMap<int, QVector<PixmapTile>> levelMap;. The out seemed to work, but on in it is having a problem with QVector<PixmapTile>.

    /home/xxx/Qt/5.10.0/gcc_64/include/QtCore/qdatastream.h:242: error: no match for ‘operator>>’ (operand types are ‘QDataStream’ and ‘QVector<PixmapTile>::value_type {aka PixmapTile}’)
             s >> t;
     QDataStream &operator<<(QDataStream &s, const PixmapTile &pixmt);
    QDataStream &operator<<(QDataStream &s, PixmapTile &pixmt);
    QDataStream &operator<<(QDataStream &s, QVector<PixmapTile> &vofpt);
    

    Am I asking too much?


  • Lifetime Qt Champion

    IIRC, you don't need to implement the QVector version because it should be automatically handled as you implemented the operators for your custom data type.

    There might be a typo you only have operator<< declared in your last code sample.



  • @SGaist Good eyes.

    QDataStream &operator>>(QDataStream &s, PixmapTile &pixmt);
    //QDataStream &operator<<(QDataStream &s, QVector<PixmapTile> &vofpt);
    

    Got it to compile. Copy and paste can bit you. Thanks.



  • @ofmrew I checked it with the debugger and it looks good. I am impressed.



  • @ofmrew said in Serialization Example:

    QDataStream &operator<<(QDataStream &s, QVector<PixmapTile> &vofpt);

    As mentioned by @SGaist you don't need to implement the operator for QVector<PixmapTile>. Qt already has template operators for QMap and QVector you just need to implement QDataStream &operator>>(QDataStream &s, PixmapTile &pixmt); and QDataStream &operator<<(QDataStream &s, const PixmapTile &pixmt);. the rest is for free


Log in to reply