PDA

View Full Version : QtMapStream - serialization of object class to QVariantMap.



benlau
10th December 2011, 11:17
Hi,

If you need to convert a lots of you own non-QObject based class to XML/YAML/JSON etc. You may be interested with my tiny project - QtMapStream.

Source code:
https://gitorious.org/qtmapstream/qtmapstream#more

QVariantMap is a synonym of QMap<QString, QVariant>. It could represent any complex objects. Convert
a QVariantMap instance to data serialization formats like XML , JSON and YAML is much easier than
a complex objects in C++. However, convert a C++ class to QVariantMap is not strict forward. User
have to implements their own convertion function.

The QtMapStream provides an interface and utility to convert user's own C++ class , which is not based
on QObject , to QVariantMap and vice versa.

Example class:


class Book {
public:
QString title;
int pages;
qreal rating;
}


You should add the QT_MAP_STREAMABLE / QT_MAP_STREAMABLE_ITEM macro to the class declaration:



class Book {
public:
QString title;
int pages;
qreal rating;

QT_MAP_STREAMABLE(
QT_MAP_STREAMABLE_ITEM(QString,title)
QT_MAP_STREAMABLE_ITEM(int,pages)
QT_MAP_STREAMABLE_ITEM(qreal,rating)
)
};


The macro will add <<,>> operators overloading with taking a QtMapStream to the class.

Convert to QVariantMap




Book book;
book.title = "Qt Developer Guides";
book.pages = 180;
book.rating = 10.0;

QtMapStream stream;
book >> stream;

QVariantMap source = stream.source(); // It will return the QVariantMap writen by the book instance.

qDebug() << source; // QMap(("pages", QVariant(int, 180) ) ( "rating" , QVariant(double, 10) ) ( "title" , QVariant(QString, "Qt Developer Guides") ) )



Convert from QVariantMap



Book book;
QVariantMap map;
map["title"] = "Qt Developer Guides";
map["pages"] = 180;
map["rating"] = 10.0;

QtMapStream stream(map);
book << stream; // The book instance will be filled with the information in QVariantmap

QVariantMap remaining = stream.source(); // After run the << stream operators, written field will be removed from the source. Call source() should return an empty map.


QtMapStream also support QList type. However, QList type can not be converted to QVariant directly. You should declare the QList type with Q_DECLARE_METATYPE first.

Example:



Q_DECLARE_METATYPE(QList<QString>)

class BookV2 {
public:
QString title;
int pages;
qreal rating;
QList<QString> authors;

QT_MAP_STREAMABLE(
QT_MAP_STREAMABLE_ITEM(QString,title)
QT_MAP_STREAMABLE_ITEM(int,pages)
QT_MAP_STREAMABLE_ITEM(qreal,rating)
QT_MAP_STREAMABLE_ITEM(QList<QString> ,authors)
)
};


Author : Ben Lau
License: New BSD