Results 1 to 2 of 2

Thread: Help with Q_PROPERTY with object pointer

  1. #1
    Join Date
    Dec 2006
    Posts
    426
    Thanks
    8
    Thanked 18 Times in 17 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Help with Q_PROPERTY with object pointer

    Hello,

    I am trying to have a generic save/restore for QObject which contain QObject derived pointer, as shown in the example, the "Parent" has "Object", but I can't use
    Q_PROPERTY( QObject *object READ object WRITE setObject )

    I would like to use
    Q_PROPERTY( Object *object READ object WRITE setObject )

    In this way, I don't need to cast from QObject to Object. Is there a way for that? Thanks!

    Qt Code:
    1. #include <QObject>
    2. #include <QString>
    3. #include <QFile>
    4. #include <QDebug>
    5. #include <QMap>
    6. #include <QDataStream>
    7. #include <QMetaObject>
    8. #include <QByteArray>
    9. #include <QVariant>
    10. #include <QMetaProperty>
    11. #include <QList>
    12. #include <QMetaType>
    13. #include <QBuffer>
    14. #include <iostream>
    15.  
    16. class Object : public QObject
    17. {
    18. Q_OBJECT
    19. Q_PROPERTY(QString string READ string WRITE setString)
    20.  
    21. public:
    22.  
    23. Object() {
    24. }
    25.  
    26. const QString& string() const {
    27. return str;
    28. }
    29.  
    30. void setString(const QString &ss) {
    31. str = ss;
    32. }
    33.  
    34. void dump() const {
    35. std::cout << str.toStdString() << std::endl;
    36. }
    37.  
    38. private:
    39.  
    40. QString str;
    41.  
    42. };
    43.  
    44.  
    45. class Parent : public QObject
    46. {
    47. Q_OBJECT
    48. Q_PROPERTY(QObject *object READ object WRITE setObject)
    49.  
    50. public:
    51.  
    52. Parent() {
    53. }
    54.  
    55. QObject * object() const {
    56. return obj;
    57. }
    58.  
    59. void setObject(QObject * oo) {
    60. Q_ASSERT(!oo || qobject_cast<Object*>(oo));
    61. obj = qobject_cast<Object*>(oo);
    62. }
    63.  
    64. private:
    65.  
    66. Object *obj;
    67.  
    68. };
    69.  
    70. class BaseInterface
    71. {
    72. public:
    73.  
    74. virtual ~BaseInterface() {}
    75. virtual QObject *create( const QString &objectName) const = 0;
    76.  
    77. };
    78.  
    79. template <typename T>
    80. class Creator : public BaseInterface
    81. {
    82. public:
    83.  
    84. QObject *create( const QString &objectName) const {
    85. T *ret = new T;
    86. ret->setObjectName(objectName);
    87. return ret;
    88. }
    89. };
    90.  
    91. class Factory
    92. {
    93. public:
    94.  
    95. static QObject *create(const QString &className, const QString &objectName) {
    96. BaseInterface *i = interfaces.value(className, 0);
    97. assert (i);
    98. return i->create(objectName);
    99. }
    100.  
    101. static void registerClass(const QString &className, BaseInterface *interface) {
    102. if (!interface) {
    103. delete interfaces.value(className, 0);
    104. interfaces.remove(className);
    105. } else {
    106. interfaces[className] = interface;
    107. }
    108. }
    109.  
    110. static QMap<QString, BaseInterface*> interfaces;
    111.  
    112. };
    113.  
    114. QMap<QString, BaseInterface*> Factory::interfaces;
    115.  
    116. static void save(QObject *o, QIODevice *dev)
    117. {
    118. const QMetaObject *mo = o->metaObject();
    119. QMap<QByteArray, QVariant> properties;
    120. QMap<QByteArray, QByteArray> objectStarProperties;
    121. QMap<QByteArray, QVariantList> listProp;;
    122.  
    123. const int props = mo->propertyCount();
    124. for (int i=0; i<props; ++i) {
    125. const QMetaProperty prop = mo->property(i);
    126. if (prop.userType() == QMetaType::QObjectStar) {
    127. QObject *obj = qVariantValue<QObject*>(prop.read(o));
    128. if (obj) {
    129. QBuffer buf;
    130. buf.open(QIODevice::WriteOnly);
    131. save(obj, &buf);
    132. objectStarProperties[prop.name()] = buf.buffer();
    133. }
    134. } else if (prop.userType() == QMetaType::QVariantList) {
    135. listProp[prop.name()] = prop.read(o).toList();
    136. } else {
    137. properties[prop.name()] = prop.read(o);
    138. }
    139. }
    140.  
    141. QDataStream ds(dev);
    142. ds << QString::fromLatin1(mo->className());
    143. ds << properties;
    144. ds << objectStarProperties;
    145.  
    146. ds << listProp.size();
    147. QMapIterator<QByteArray, QVariantList> it1( listProp );
    148. while( it1.hasNext() ) {
    149. it1.next();
    150. QVariantList vlist = it1.value();
    151. ds << vlist.size() << it1.key();
    152. }
    153.  
    154. }
    155. static QObject *read(QIODevice *dev, QObject *parent = 0)
    156. {
    157. QString className;
    158. QMap<QByteArray, QVariant> properties;
    159. QMap<QByteArray, QByteArray> objectStarProperties;
    160.  
    161. QDataStream ds(dev);
    162.  
    163. ds >> className;
    164. ds >> properties;
    165. ds >> objectStarProperties;
    166.  
    167. int nlists;
    168. ds >> nlists;
    169.  
    170. QList<int> iList;
    171. QList<QByteArray> propNameList;
    172. for ( int idx=0; idx<nlists; idx++ ) {
    173. int il;
    174. ds >> il >> pnl;
    175. iList.append( il );
    176. propNameList.append( pnl );
    177. }
    178.  
    179. QObject *o = Factory::create(className,
    180. properties.value("objectName").toString());
    181. if (!o) {
    182. qWarning() << "Can't create object of type" << className;
    183. return 0;
    184. }
    185.  
    186. for (QMap<QByteArray, QVariant>::const_iterator it = properties.begin();
    187. it != properties.end(); ++it) {
    188. if (!o->setProperty(it.key().constData(), it.value())) {
    189. qWarning() << "Can't set" << it.key();
    190. }
    191. }
    192.  
    193. for (QMap<QByteArray, QByteArray>::const_iterator it =
    194. objectStarProperties.begin();
    195. it != objectStarProperties.end(); ++it) {
    196. QBuffer buf;
    197. buf.setData(it.value());
    198. buf.open(QIODevice::ReadOnly);
    199. QObject *obj = read(&buf, 0);
    200. o->setProperty(it.key(), qVariantFromValue<QObject*>(obj));
    201. }
    202.  
    203. for ( int idx=0; idx<nlists; idx++ ) {
    204. QVariantList objList;
    205. for (int ii=0; ii<iList[idx]; ++ii) {
    206. QObject* oo = read(dev, o);
    207. objList << qVariantFromValue<QObject*>( oo );
    208. }
    209. o->setProperty( propNameList[idx], objList );
    210. }
    211.  
    212. return o;
    213.  
    214. }
    215.  
    216. #include "main.moc"
    217.  
    218. int main()
    219. {
    220. Factory::registerClass("Parent", new Creator<Parent>());
    221. Factory::registerClass("Object", new Creator<Object>());
    222.  
    223. Object *o = new Object;
    224. o->setString("foobar");
    225.  
    226. Parent *p = new Parent;
    227. p->setObject(o);
    228.  
    229. qobject_cast<Object*>( p->object() )->dump();
    230.  
    231. QFile file("tt.ss");
    232. file.open(QIODevice::WriteOnly);
    233.  
    234. save(p, &file);
    235. file.close();
    236.  
    237. file.open(QIODevice::ReadOnly);
    238.  
    239. QObject *root = read(&file);
    240. Q_ASSERT(root);
    241. Parent *pp = qobject_cast<Parent*>(root);
    242.  
    243. qobject_cast<Object*>( pp->object() )->dump();
    244.  
    245. return 0;
    246. }
    To copy to clipboard, switch view to plain text mode 

  2. #2
    Join Date
    Feb 2006
    Location
    Oslo, Norway
    Posts
    6,264
    Thanks
    36
    Thanked 1,518 Times in 1,388 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows Symbian S60 Maemo/MeeGo

    Default Re: Help with Q_PROPERTY with object pointer

    Properties tend to be value types. Does it make sense to serialize a pointer value to a file?
    J-P Nurmi

Similar Threads

  1. static Object Vs Pointer
    By rajeshs in forum General Programming
    Replies: 4
    Last Post: 11th June 2008, 07:41
  2. Saving object pointer
    By MarkoSan in forum General Programming
    Replies: 4
    Last Post: 11th January 2008, 11:53
  3. Pointer to ActiveX object in QT
    By json84 in forum Qt Programming
    Replies: 1
    Last Post: 15th June 2007, 12:42
  4. simple pointer question
    By mickey in forum General Programming
    Replies: 6
    Last Post: 16th June 2006, 09:19
  5. Signals destroys my pointer
    By Jojo in forum Qt Programming
    Replies: 12
    Last Post: 7th March 2006, 21:05

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.