什么时候应该使用Q_OBJECT?
该文件指出:
Q_OBJECTmacros必须出现在声明自己的信号和槽或者使用Qt的元对象系统提供的其他服务的类定义的私有部分。
但究竟是什么意思? 哪些QObject派生类可以安全地忽略它? 如果您在QObject派生类中省略Q_OBJECT,然后inheritance它,会出现问题吗? 基本上我想知道什么时候可以从我的Qt类中忽略它。
您应该使用Q_OBJECT
macros来从QObject
派生的任何非模板类 。
除了信号和插槽之外, Q_OBJECT
macros还提供了与给定类关联的元对象信息 。
正如文件中所述 :
我们强烈build议QObject的所有子类使用Q_OBJECTmacros,而不pipe它们是否实际使用信号,槽和属性。
假设我们有以下类:
class Class : public QObject { public: Class() {} };
如果没有Q_OBJECT
,以下元对象系统function(除其他外)将不能用于Class
:
-
qobject_cast<Class>()
– 由于缺less元数据 -
QObject::tr()
– 由于缺less元数据 -
在
Class
首先声明的插槽和可调用对象,当调用或按名称查找时,QMetaObject
方法都不适用于这些方法,Qt 4也不会connect
– 由于缺less元数据 -
信号 – 因为
moc
不会生成它们的实现,代码将不能编译。
当然,你可以忽略它,但是如果你使用了这些特性,你需要记住把macros放入类的声明中。 这是一个相当脆弱的做法,最好避免。 节省是不值得的。 因此,不要等待 – 将Q_OBJECT
macros添加到从QObject
派生的每个类作为编码策略的问题。
Q_OBJECT
macros不应该用于不从QObject
派生的类。 要添加可调用和属性到这些类,请改用Q_GADGET
macros。
如果你想使用信号/插槽,你必须包含Q_OBJECTmacros,并从QObject派生类。
否则,你可以把它排除在外,但是把它包含在所有的Qt gui类中并没有什么坏处
那么第一部分是非常清楚的,因为你可能已经知道..信号和插槽,Meta对象系统的其余部分是一个稍微知道。 也许更有用的function之一是dynamic属性。 虽然这些东西有很多用途,但是我用它们来利用Qt的animation系统QPropertyAnimation
。
这里有一些关于元对象系统的信息: http : //doc.qt.io/archives/4.6/metaobjects.html
我认为底线是,如果从QObject层次结构inheritance,则不pipe是否抛出Q_OBJECTmacros。 这很简单,可以帮助您避免一些可能令人困惑的问题。
@liaK说的是正确的(简而言之,你应该总是在任何派生自QObject的类中使用Q_OBJECTmacros)。
有一件事我没有看到强调的是,如果你不明确地把Q_OBJECTmacros,那么使用有时非常方便的 qobject_cast将无法正常工作!