有没有办法使用QMetaEnum和Q_ENUMS属于非Q_OBJECT或Q_GADGET类?

时间:2016-06-07 10:45:05

标签: c++ qt qmetaobject

例如,我有以下课程:

namespace someName
{
    class someClass
    {
        Q_ENUMS(ESomeEnum)

        public:
        enum ESomeEnum {ENUM_A, ENUM_B, ENUM_C};

        // ... some other things ..
    }
}

Q_DECLARE_METATYPE(someName::someClass)

有没有办法使用QMetaEnum :: valueToKey或QMetaEnum :: keyToValue?

尝试this answer中的方法,但收到以下错误:

error: static assertion failed: QMetaEnum::fromType only works with enums declared as Q_ENUM or Q_FLAG
#define Q_STATIC_ASSERT_X(Condition, Message) static_assert(bool(Condition), Message)

我可以使用X-Macros来获得我想要的输出,但是在Qt中学习更多技巧也会很好。

3 个答案:

答案 0 :(得分:8)

不,没有,因为Q_ENUM的功能是在moc生成的代码中实现的,而moc忽略了既不是Q_OBJECT也不是Q_GADGET的类。没有理由不使用Q_GADGET,因为它对对象大小没有影响:不添加虚拟方法也不添加数据字段。

以下内容证明了这一点:

#include <QtCore>

namespace Ns {
class Class {
   Q_GADGET
public:
   enum ESomeEnum {ENUM_A, ENUM_B, ENUM_C};
   Q_ENUM(ESomeEnum)
};
}

int main() {
   auto metaEnum = QMetaEnum::fromType<Ns::Class::ESomeEnum>();
   qDebug() << sizeof(Ns::Class) << metaEnum.valueToKey(Ns::Class::ENUM_A);
}
#include "main.moc"

输出:

1 ENUM_A

在这个特定平台(以及许多其他平台)上,空类的大小为1。

答案 1 :(得分:4)

Q_ENUM与旧版Q_ENUMS类似,但存在以下差异:

  • 需要将其放在源代码中的enum之后。
  • 只能将一个enum放入宏中。
  • 启用QMetaEnum::fromType<T>()
  • 这些enum自动声明为QMetaType s(无需) 将它们添加到Q_DECLARE_METATYPE中。
  • 传递给enum
  • qDebug将打印值的名称而不是 号码。
  • 当放入QVariant时,toString()会提供值名称。值名称 由QCOMPARE打印(自Qt 5.6起)

摘自WOBOQ blog post on the topic,请阅读以获取有关Q_ENUMQ_ENUMS的其他信息。

答案 2 :(得分:0)

是的,从5.8开始,您可以这样做:

namespace MyLibrary
{ 
Q_NAMESPACE 

enum class MYLIBRARYSHARED_EXPORT MyEnumClass
{
...
}; 

Q_ENUM_NS(MyEnumClass)

...
} // namespace MyLibrary