Custom class serialize with QDataStream
-
Hi Everybody,
I have got a TreeItem custom class (not derived from QObject) which is "wrapped" into QVariant and i would like to serialize and deserialize it with QDataStream.
TreeItem represents a multi-level Tree with a list of child pointers and a parent pointer.
I placed the implemented operator<< and operator>> methods before main() method and qRegisterMetaTypeStreamOperators<TreeItem>("TreeItem"); in the first line of main() method.
I have defined a Q_DECLARE_METATYPE(TreeItem*) macro too.See above:
#include "TheApp.h" #include <QtWidgets/QApplication> #include "TreeItem.h" QDataStream &operator<<(QDataStream &out, const TreeItem &rhs) { out.writeRawData(reinterpret_cast<const char*>(&rhs), sizeof(rhs)); return out; } QDataStream &operator>>(QDataStream &in, TreeItem &rhs) { in.readRawData(reinterpret_cast<char*>(&rhs), sizeof(rhs)); return in; } int main(int argc, char *argv[]) { QApplication a(argc, argv); qRegisterMetaTypeStreamOperators<TreeItem>("TreeItem"); QCoreApplication::setApplicationName(QString("TheApp")); TheApp w; w.show(); return a.exec(); }
I would like to encode it with the following:
QByteArray encodedData; QDataStream stream(&encodedData, QIODevice::WriteOnly); TreeItem* treeItem = new TreeItem(); QVariant treeItemQVariant = QVariant::fromValue(treeItem); stream << treeItemQVariant;
When i execute "stream << treeItemQVariant;" i got this error message:
QVariant::save: unable to save type 'TreeItem*' (type id: 1037). ASSERT failure in QVariant::save: "Invalid type to save", file kernel\qvariant.cpp, line 2144 Debug Error!
What is the problem?
How can i (de)serialize a custom class with QDataStream which is "wrapped" into a QVariant?Thanks in advance,
It should be a big help for me,
BR,
Peter -
I don't like your serialisation with reinterpret_cast but the main point here is that you are getting confused by the pointer.
change
Q_DECLARE_METATYPE(TreeItem*)
toQ_DECLARE_METATYPE(TreeItem)
and changeQVariant treeItemQVariant = QVariant::fromValue(treeItem);
toQVariant treeItemQVariant = QVariant::fromValue(*treeItem);
(be carefull not to leak treeItem)@pvt.peter said in Custom class serialize with QDataStream:
How can i (de)serialize a custom class with QDataStream which is "wrapped" into a QVariant?
QVariant TempVariant; stream >> TempVariant; *treeItem = TempVariant.value<TreeItem>();
P.S.
in your code snippet you don't really need to pass through QVariant btw, you can just usestream << *treeItem;
-
@VRonin Thanks for your reply, i did your modifications and it works with QVariant.
But how can i use stream << *treeItem; ?
Now i use the following codes:Q_DECLARE_METATYPE(TreeItem)
QDataStream &operator<<(QDataStream &out, const TreeItem& rhs) { out.writeRawData(reinterpret_cast<const char*>(&rhs), sizeof(rhs)); return out; } QDataStream &operator>>(QDataStream &in, TreeItem &rhs) { in.readRawData(reinterpret_cast<char*>(&rhs), sizeof(rhs)); return in; }
qRegisterMetaTypeStreamOperators<TreeItem>("TreeItem");
TreeItem* treeItem = new TreeItem(); stream << *treeItem;
TreeItem* data2 = nullptr; while (!stream.atEnd()) { stream >> *data2; }
There are some trouble with operator << and operator >>.
No 'operator <<' matches arguments of type 'QDataStream' and 'TreeItem'
No 'operator >>' matches arguments of type 'QDataStream' and 'TreeItem'
How can i fix them? -
@VRonin said in Custom class serialize with QDataStream:
I don't like your serialisation with reinterpret_cast
What is wrong with it? Is there any real risk associatied with using it in such situation? Or is it just a prejuidice because it is generally regarded to be unsafe?