12.5.  Dynamic Properties

[ fromfile: reflection.xml id: dynamicproperties ]

Example 12.8. src/properties/dynamic/dynoprops.h

[ . . . . ]
class DynoProps : public QObject {
    Q_OBJECT
    Q_PROPERTY(QString someString READ someString WRITE setSomeString);
 public:
    friend QDataStream& operator<<(QDataStream& os, const DynoProps& dp);
    friend QDataStream& operator>>(QDataStream& is, DynoProps& dp);
    QString someString() { return m_someString; }
    void setSomeString(QString ss) { m_someString = ss; }
    QString propsInventory();
 private:
    QString m_someString;
};
[ . . . . ]

Example 12.9. src/properties/dynamic/dynoprops.cpp

[ . . . . ]

QString DynoProps::propsInventory() {
   static const QMetaObject* meta = metaObject();
   QStringList res;
   res << "Fixed Properties:";
   QString propData;
   for(int i = 0; i < meta->propertyCount(); ++i) {
      res << QString("%1\t%2").arg(QString(meta->property(i).name()))
              .arg(meta->property(i).read(this).toString());  1
   }
   res << "Dynamic Properties:";  
   foreach(QByteArray dpname, dynamicPropertyNames()) {
      res << QString("%1\t%2").arg(QString(dpname))
              .arg(property(dpname).toString());
   }
   return res.join("\n");
}
 

1

We could also use property(propName) here.


Example 12.10. src/properties/dynamic/dynoprops.cpp

[ . . . . ]
 QDataStream& operator<< (QDataStream& os, const DynoProps& dp) {
   static const QMetaObject* meta = dp.metaObject();
   for(int i = 0; i < meta->propertyCount(); ++i) {
        const char* name = meta->property(i).name();
        os << QString::fromLocal8Bit(name)              1
           << dp.property(name);
   }
   qint32 N(dp.dynamicPropertyNames().count());         2
   os << N;
   foreach(QByteArray propname, dp.dynamicPropertyNames()) {
      os << QString::fromLocal8Bit(propname) << dp.property(propname);
   }
   return os;
 }
 
 QDataStream& operator>> (QDataStream& is, DynoProps& dp) {
   static const QMetaObject* meta = dp.metaObject();
   QString propname;
   QVariant propqv;
   int propcount(meta->propertyCount());
   for(int i = 0; i < propcount; ++i) {
      is >> propname;
      is >> propqv;
      dp.setProperty(propname.toLocal8Bit(), propqv);   3
   }
   qint32 dpcount;
   is >> dpcount;
   for(int i = 0; i < dpcount; ++i) {
      is >> propname;
      is >> propqv;
      dp.setProperty(propname.toLocal8Bit(), propqv);
   }
   return is;
 }

1

To serialize a char* as a QString

2

To serialize an int

3

De-serialize char* using reverse QString conversion


Example 12.11. src/properties/dynamic/dynoprops-client.cpp

#include <QtCore>
#include "dynoprops.h"

int main() {
   QTextStream cout(stdout);
   DynoProps d1, d2;
   d1.setObjectName("d1");
   d2.setObjectName("d2");
   d1.setSomeString("Washington");
   d1.setProperty("AcquiredProp", "StringValue");
   d2.setProperty("intProp", 42);
   d2.setProperty("realProp", 3.14159);
   d2.setProperty("dateProp", QDate(2012, 01, 04));
   cout << d1.propsInventory() << endl;
   cout << d2.propsInventory() << endl;
   cout << "\nNow we save both objects to a file, close the file,\n"
           "reopen the file, read the data from the file, and use it\n"
           "to create new DynoProps objects.\n" << endl;
   QFile file("file.dat");
   file.open(QIODevice::WriteOnly);
   QDataStream out(&file);
   out << d1 << d2;
   file.close();
   DynoProps nd1, nd2;
   file.open(QIODevice::ReadOnly);
   QDataStream in(&file);
   in >> nd1 >> nd2;
   file.close();
   cout << "Here are the property inventories for the new objects.\n";
   cout << nd1.propsInventory() << endl;
   cout << nd2.propsInventory() << endl;   
}
                                            

Example 12.12. src/properties/dynamic/output.txt

Fixed Properties:
objectName      d1
someString      Washington
Dynamic Properties:
AcquiredProp    StringValue
Fixed Properties:
objectName      d2
someString
Dynamic Properties:
intProp 42
realProp        3.14159
dateProp        2012-01-04

Now we save both objects to a file, close the file,
reopen the file, read the data from the file, and use it
to create new DynoProps objects.

Here are the property inventories for the new objects.
Fixed Properties:
objectName      d1
someString      Washington
Dynamic Properties:
AcquiredProp    StringValue
Fixed Properties:
objectName      d2
someString
Dynamic Properties:
intProp 42
realProp        3.14159
dateProp        2012-01-04