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: };
-
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){ ^
-
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. -
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?
-
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?
-
Copy the methods as they are in the implementation file and just leave the declaration in the header.
-
@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 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?
-
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. -
@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 forQMap
andQVector
you just need to implementQDataStream &operator>>(QDataStream &s, PixmapTile &pixmt);
andQDataStream &operator<<(QDataStream &s, const PixmapTile &pixmt);
. the rest is for free