无法从另一个类中定义的枚举声明Q_ENUM

时间:2014-09-11 19:03:35

标签: c++ qt

This documentation

  

如果要注册在另一个类中声明的枚举,则枚举必须使用定义它的类的名称进行完全限定。此外,定义枚举的类必须继承QObject,并使用Q_ENUMS()声明枚举。

但是,在下面的示例中,我无法完成这项工作。

A类:

#ifndef CLASSA_H
#define CLASSA_H

#include <classb.h>

class ClassA : public QObject
{
   Q_OBJECT
   Q_ENUMS(ClassB::TestEnum)

public:
   explicit ClassA(QObject *parent = 0) : QObject(parent)
   {
      const QMetaObject *metaObj = this->metaObject();
      qDebug() << metaObj->enumeratorCount();
   }
};

#endif // CLASSA_H

ClassB:

#ifndef CLASSB_H
#define CLASSB_H

#include <QDebug>
#include <QMetaEnum>
#include <QObject>

class ClassB : public QObject
{
   Q_OBJECT
   Q_ENUMS(TestEnum)

public:
   enum TestEnum { A, B, C };

   explicit ClassB(QObject *parent = 0) : QObject(parent)
   {
      const QMetaObject *metaObj = this->metaObject();
      qDebug() << metaObj->enumeratorCount();
   }
};

#endif // CLASSB_H

主:

#include <classa.h>
#include <classb.h>

int main() 
{
   ClassA objectA;
   ClassB objectB; 
}

预期产出:

1

1

实际输出:

0

1

1 个答案:

答案 0 :(得分:5)

以下是一项小型研究的总结:

  • 有关在另一个类中声明的枚举注册的文档中所述的信息看起来过时了。

  • Q_ENUMS(Class::EnumName不会创建新的枚举器,也没用。

  • 在ClassA中声明新的Q_PROPERTY时,您应该使用枚举ClassB::EnumName的完整形式。

  • 只要在ClassB中注册了EnumName,就不需要再注册了。

  • 使用其他类的枚举器创建的属性可以正常工作。

    class ClassA : public QObject
    {
    public:
     Q_OBJECT       
     Q_PROPERTY(ClassB::TestEnum test READ test)
    
    public:
    explicit ClassA(QObject *parent = 0)
    {
        const QMetaObject *metaObj = this->metaObject();
        qDebug() << metaObj->enumeratorCount();
    
        QMetaProperty property = metaObj->property(metaObj->indexOfProperty("test"));
        if (property.isEnumType())
        {
            const QMetaEnum& enumerator = property.enumerator();
    
            qDebug() << enumerator.name();
    
            for (int i = 0 ; i < enumerator.keyCount(); i++)
            {
                qDebug() << QLatin1String(enumerator.key(i)) <<  enumerator.value(i);           
            }
        }
    }
    ClassB::TestEnum test() const
    {
        return ClassB::A;
    }
    };
    

输出:

0 
TestEnum 
"A" 0 
"B" 1 
"C" 2