7

I think I can write a QObject like this by taking advantage of the Q_PROPERTYs:

QDataStream &operator<<(QDataStream &ds, const Object &obj) {
    for(int i=0; i<obj.metaObject()->propertyCount(); ++i) {
        if(obj.metaObject()->property(i).isStored(&obj)) {
            ds << obj.metaObject()->property(i).read(&obj);
        }
    }
    return ds;
}

Which, if that's true, I don't know why QObjects don't already have that method implemented because it's pretty generic. But that's besides the point. How would I read the file? i.e., implement this function?

QDataStream &operator>>(QDataStream &ds, Object &obj) {
    return ds;
}

I'm thinking I can somehow use ds.readBytes but how would I get the length of the property?

PS: If it wasn't obvious, Object is my custom class that inherits from QObject.

mpen
  • 272,448
  • 266
  • 850
  • 1,236
  • 2
    I don't think QObjects are supposed to be serializable. You can't even copy them. As for reading QVariant back, it is either very easy (just read it with >> into empty QVariant), or hard -- you must handle type and length yourself. – Eugene Sep 14 '09 at 01:09
  • If you are looking for serialization, you might want to look at Boost.Serialize. – Michael Aaron Safyan Sep 14 '09 at 04:27
  • @Eugene: Should have posted that as an answer... for some reason it didn't occur to me that I could just read in the `QVariant`. I figured they'd be all different sizes or something, but that's not how C++ works. – mpen Sep 14 '09 at 07:51
  • Oh, they all are different sizes. But I think QVariant writes out its type and length, besides data itself. Just enough to read it back. – Eugene Sep 15 '09 at 00:53
  • Oh. I thought it was some big union mess internally... which means it would be the size of the largest element, no? (+ the type info of course). Anyway, it doesn't really matter. They're readable and writable :) – mpen Sep 15 '09 at 05:23
  • Heh, imagine QString in a union :) – Eugene Sep 15 '09 at 23:57
  • "The QVariant class acts like a union for the most common Qt data types." - Oh.. I guess that's where I got that idea from. What are they using then, void pointers? And what's wrong with a QString in a union... it's just a char pointer or something isn't it? – mpen Sep 16 '09 at 01:25

1 Answers1

6

This seems to work.

QDataStream &operator>>(QDataStream &ds, Object &obj) {
    QVariant var;
    for(int i=0; i<obj.metaObject()->propertyCount(); ++i) {
        if(obj.metaObject()->property(i).isStored(&obj)) {
            ds >> var;
            obj.metaObject()->property(i).write(&obj, var);
        }
    }
    return ds;
}

Thanks to Eugene.

Community
  • 1
  • 1
mpen
  • 272,448
  • 266
  • 850
  • 1,236