# Q_ENUM的作用
Q_ENUM(...)这个宏会将定义的枚举类型注册到元对象系统中。它需要放置在枚举类型的生命之后,且在一个具有Q_OBJECT, Q_GADGET或Q_GADGET_EXPORT宏的类中。如果在命名空间中,可以使用Q_ENUM_NS()来代替Q_ENUM()。
经过Q_ENUM注册过的枚举类型也会自动注册到Qt的元类型系统中,而无需再使用Q_DECLARE_METATYPE()进行注册,便可以再QMetaType中使用。例如,如果在QVariant使用了注册过的类型,它就可以被转换成相应的字符串;同样的,QDebug也可以直接打印出它的名字。
不过需要注意的是:枚举变量的值是以有符号整型被注册到元对象系统的。注册的枚举类型的值如果超出了有符号整型的范围时,就会发生溢出进而导致未定义的行为。
# Q_ENUM的例子
我们来看一个Q_ENUM的例子,我们定义了一个继承至QObject的类MyClass,在这个类中,我们定义了一个priority的属性,它是一个枚举类型的变量,为了属性及相应的信号与槽能够使用这个枚举类型,我们使用Q_ENUM对枚举类型Proiority进行了注册。
~~~
class MyClass : public QObject
{
Q_OBJECT
Q_PROPERTY(Priority priority READ priority WRITE setPriority NOTIFY priorityChanged)
public:
MyClass(QObject *parent = nullptr);
~MyClass();
enum Priority { High, Low, VeryHigh, VeryLow };
Q_ENUM(Priority)
void setPriority(Priority priority)
{
m_priority = priority;
emit priorityChanged(priority);
}
Priority priority() const
{ return m_priority; }
signals:
void priorityChanged(Priority);
private:
Priority m_priority;
};
~~~
借助于Qt的元属性系统,我们既可以直接使用priority属性对应的WRITE函数,setPriority来设置对应的值,也可以通过设置属性函数setProperty来设置priority的值,如下:
~~~
MyClass *myinstance = new MyClass;
QObject *object = myinstance;
myinstance->setPriority(MyClass::VeryHigh);
object->setProperty("priority", "VeryHigh");
~~~
另外,大家在使用中需要注意:
1. 如果修改相应的枚举类型名时,需要着重注意一下Q_PROPERTY内对应的类型名,因为vs的解析并没有解析到Q_PROPERTY内部的变量和函数名;
2. 枚举类型的命名尽量不要使用下划线,因为moc在进行文件转换时,有时会出现找不到相应定义的变量名的错误;不过后续重新写了一遍之后,错误就消失了,没有排查到具体是什么原因,同样的代码用QT Creator编译就没有问题,使用VS+QT addin编译就出现了错误,为了避免不必要的问题,建议枚举类型的命名尽量不要使用下划线。