什么时候应该使用Q_OBJECT?

该文件指出:

Q_OBJECTmacros必须出现在声明自己的信号和槽或者使用Qt的元对象系统提供的其他服务的类定义的私有部分。

究竟是什么意思? 哪些QObject派生类可以安全地忽略它? 如果您在QObject派生类中省略Q_OBJECT,然后inheritance它,会出现问题吗? 基本上我想知道什么时候可以从我的Qt类中忽略它。

您应该使用Q_OBJECTmacros来从QObject派生的任何非模板类

除了信号和插槽之外, Q_OBJECTmacros还提供了与给定类关联的元对象信息

正如文件中所述 :

我们强烈build议QObject的所有子类使用Q_OBJECTmacros,而不pipe它们是否实际使用信号,槽和属性。

假设我们有以下类:

 class Class : public QObject { public: Class() {} }; 

如果没有Q_OBJECT ,以下元对象系统function(除其他外)将不能用于Class

  1. qobject_cast<Class>() – 由于缺less元数据

  2. QObject::tr() – 由于缺less元数据

  3. Class首先声明的插槽和可调用对象,当调用或按名称查找时, QMetaObject方法都不适用于这些方法,Qt 4也不会connect – 由于缺less元数据

  4. 信号 – 因为moc不会生成它们的实现,代码将不能编译。

当然,你可以忽略它,但是如果你使用了这些特性,你需要记住把macros放入类的声明中。 这是一个相当脆弱的做法,最好避免。 节省是不值得的。 因此,不要等待 – 将Q_OBJECTmacros添加到从QObject派生的每个类作为编码策略的问题。

Q_OBJECTmacros应该用于不从QObject派生的类。 要添加可调用和属性到这些类,请改用Q_GADGETmacros。

如果你想使用信号/插槽,你必须包含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将无法正常工作!