什么时候应该使用Q_OBJECT?

时间:2010-09-11 03:39:05

标签: c++ qt qobject

文件说明:

  

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

完全这是什么意思?我可以安全地省略哪些QObject派生类?如果在QObject派生类上省略Q_OBJECT,然后从那个继承,会出现问题吗?基本上我想了解更多关于何时可以从我的Qt课程中省略它的信息。

4 个答案:

答案 0 :(得分:34)

对于源自Q_OBJECT 的任何非模板化类,您应该使用QObject

除了信号和广告位,Q_OBJECT宏提供与给定类相关联的元对象信息

the documentation中所述:

  

我们强烈建议 QObject的所有子类使用Q_OBJECT宏,无论它们是否实际使用信号,插槽和属性。

假设我们有以下类:

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

如果没有Q_OBJECT,以下元对象系统功能(以及其他功能)将不适用于Class

  1. qobject_cast<Class>() - 由于缺少元数据

  2. QObject::tr() - 由于缺少元数据

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

  4. 信号 - 因为moc不会生成他们的实现,代码也不会编译。

  5. 当然,您可以省略它,但如果您使用这些功能,则需要记住将宏放入类的声明中。这是一种相当脆弱的做法,最好避免。节省下来是不值得的。所以,不要等待 - 将Q_OBJECT宏添加到源自QObject的每个类中作为编码策略。

    Q_OBJECT永远不会用于不是从QObject派生的类。要向这些类添加invokable和属性,请改用Q_GADGET宏。

答案 1 :(得分:6)

如果你想使用信号/插槽,你必须包含Q_OBJECT宏并从QObject派生类。

否则你可以将它排除在外,但将它包含在所有Qt gui类中都没有任何伤害

答案 2 :(得分:4)

第一部分非常清楚,因为你可能已经知道..信号和插槽,Meta对象系统的其余部分有点鲜为人知。也许一个更有用的功能是动态属性。虽然它们有很多用途,但我用它们来利用Qt的动画系统QPropertyAnimation

这里有关于元对象系统的更多信息:http://doc.qt.io/archives/4.6/metaobjects.html

我认为底线是,如果从QObject层次结构继承,则抛出Q_OBJECT宏。它很简单,可以帮助您避免一些令人困惑的问题。

答案 3 :(得分:2)

@liaK所说的是正确的(简而言之:你 总是在任何从QObject派生的类中使用Q_OBJECT宏。)

我没有看到的一件事是,如果你明确地放置 Q_OBJECT 宏,那么使用有时非常方便 qobject_cast将无效!!!