[Solved] Storing container with enums in QSettings



  • Hi,

    I have the following structure:
    @
    enum Eye {
    Invalid,
    OS,
    OD
    };
    Q_DECLARE_METATYPE(Eye)

    enum Field {
    Invalid,
    Nasal,
    Central
    };
    Q_DECLARE_METATYPE(Field)

    typedef QPair<Eye, Field> EyeField;
    Q_DECLARE_METATYPE(EyeField)
    typedef QVector<EyeField> EyeFieldList;
    Q_DECLARE_METATYPE(EyeFieldList)

    inline QDataStream& operator>>(QDataStream& in, Eye& e)
    {
    in >> (quint32&)e;
    return in;
    }

    inline QDataStream& operator<<(QDataStream& out, Eye& e)
    {
    out << (quint32&)e;
    return out;
    }

    inline QDataStream& operator>>(QDataStream& in, Field& e)
    {
    in >> (quint32&)e;
    return in;
    }

    inline QDataStream& operator<<(QDataStream& out, Field& e)
    {
    out << (quint32&)e;
    return out;
    }

    //in C++ file
    //ran at startup
    qRegisterMetaType<Eye>("Eye");
    qRegisterMetaType<Field>("Field");
    qRegisterMetaTypeStreamOperators<Eye>("Eye");
    qRegisterMetaTypeStreamOperators<Field>("Field");

    // ...

    QVariantHash settings; //contains, among other things, an EyeFieldList

    //...

    QSettings registry;
    registry.setValue("settings", settings); // BOOM!
    @

    I can't find how am supposed to make this work. I think I have defined all the needed Q_DECLARE_METATYPE, used qDeclareMetatype on all types used, and even implemented QDataStream operators for the enums (had to be inline, otherwise I'd get compilation errors on multiple definitions). Nothings helps. It compiles fine, but I still get crashes. Any tips on how to make this actually work?

    Edit:
    I have added the meta-type stuff and QDataStream implementations to the code.



  • isn' t missing ";" after the definition of the enum ?



  • [quote author="Neutron Stein" date="1343732053"]isn' t missing ";" after the definition of the enum ?[/quote]
    It is (in the sample above, not in my actual code), but that is not my issue. Thanks for noticing though.



  • Can you insert a QVariantHash in QSettings? Or did you mean to iterate over the QVariantHash and insert the keys and values one by one ?
    So instead of this:
    @
    QVariantHash settings; //contains, among other things, an EyeFieldList
    QSettings registry;
    registry.setValue("settings", settings); // BOOM!
    @

    Something like this:
    @
    QVariantHash settings; //contains, among other things, an EyeFieldList
    QSettings registry;
    QVariantHash::const_iterator it = settings.constBegin();
    while(it != settings.constEnd())
    {
    registry.setValue(it.key(), it.value());
    it++;
    }
    @



  • Nope, I wanted to stick the QVariantHash itself in QSettings. Let Qt handle the serialization instead of me :-)

    However, I just managed to get it to work. It seems that you need to use Q_DECLARE_METATYPE and qRegisterMetaType for all containers involved. So, in my case, that involved:

    @
    qRegisterMetaType<Eye>("Eye");
    qRegisterMetaType<Field>("Field");
    qRegisterMetaType<EyeField>("EyeField");
    qRegisterMetaType<EyeFieldList>("EyeFieldList");
    qRegisterMetaTypeStreamOperators<Eye>("Eye");
    qRegisterMetaTypeStreamOperators<Field>("Field");
    qRegisterMetaTypeStreamOperators<EyeField>("EyeField");
    qRegisterMetaTypeStreamOperators<EyeFieldList>("EyeFieldList");
    @

    And actually a few more, that I left out of this example for the sake of keeping the overview.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.