Important: Please read the Qt Code of Conduct -

Q_PROPERTY of enum type, declared in some namespace

  • Hi everybody,

    I'd like to improve the accessibility of my classes via Q_PROPERTY macros. Some of the methods take types though, that aren't defined in the class itself, but in some global namespace (like the Qt:: namespace).
    For example:
    namespace ns {
    enum myEnum {meOne, meTwo};

    class A : public QObject
    Q_PROPERTY(ns::myEnum something READ something WRITE setSomething)

    void setSomething(ns::myEnum value);
    ns::myEnum something();

    Like this, the compiler reports the error:
    'staticMetaObject' is not a member of 'ns'
    Which I understand, because Qt's meta-object-system doesn't have a grasp of that enum. So I tried adding Q_ENUMS(myEnum) inside the namespace, aswell as Q_ENUMS(ns::myEnum) outside. Both didn't change anything.
    Then I tried adding Q_DECLARE_METATYPE(ns::myEnum) after the namespace and the compile worked fine.

    So here are my questions about this:

    • What is the correct way to achieve this?
    • In the docs both Q_DECLARE_METATYPE and Q_ENUMS are said to "register a type with the meta-object-system", yet the former works, the latter doesn't, in this case. Why?
    • The docs further say, I must call qRegisterMetaType when using Q_DECLARE_METATYPE. Is this also necessary in this case? Where would I call it? every time A is constructed in its constructor? (Wouldn't that cause multiple register attempts?)

    I've looked at qnamespace.h to see how they do a similar thing, but it is a huge hackfest. via macros and defines, they fake a class with the same name as the namespace and only during non-moc runs it is left as a namespace... Do I also have to hack like this? (I'd rather abandon the property system then...)

  • push push

  • Moderators

    Well if you don't mind a few bytes of overhead then just put your enums into a single class with Q_GADGET macro, add a private constructor and be done with it. Come to think of it the compiler will probably optimize away the unused class overhead anyway (or not, whatever).
    Syntactically there is no difference if it's a class or a namespace if you're just using it for enum metadata.
    class MyEnums {
    Q_ENUMS(MyEnum1 MyEnum2)
    enum MyEnum1 { Val1, Val2, Val3};
    enum MyEnum2 { Val4, Val5, Val6};
    Q_DECLARE_FLAGS(MyEnums1, MyEnum1)

  • const QMetaObject qtMo = *qt_getQtMetaObject();

Log in to reply