文件说明:
Q_OBJECT宏必须出现在 类定义的私有部分 声明自己的信号和 插槽或使用其他服务 由Qt的元对象系统提供。
但完全这是什么意思?我可以安全地省略哪些QObject派生类?如果在QObject派生类上省略Q_OBJECT,然后从那个继承,会出现问题吗?基本上我想了解更多关于何时可以从我的Qt课程中省略它的信息。
答案 0 :(得分:34)
对于源自Q_OBJECT
的任何非模板化类,您应该使用QObject
宏。
除了信号和广告位,Q_OBJECT
宏提供与给定类相关联的元对象信息。
如the documentation中所述:
我们强烈建议 QObject的所有子类使用Q_OBJECT宏,无论它们是否实际使用信号,插槽和属性。
假设我们有以下类:
class Class : public QObject {
public:
Class() {}
};
如果没有Q_OBJECT
,以下元对象系统功能(以及其他功能)将不适用于Class
:
qobject_cast<Class>()
- 由于缺少元数据
QObject::tr()
- 由于缺少元数据
首先在Class
中声明的插槽和invokable,当按名称调用或查找时 - QMetaObject
方法都不适用于这些方法,Qt 4 connect
也不会 - 由于缺少元数据
信号 - 因为moc
不会生成他们的实现,代码也不会编译。
当然,您可以省略它,但如果您使用这些功能,则需要记住将宏放入类的声明中。这是一种相当脆弱的做法,最好避免。节省下来是不值得的。所以,不要等待 - 将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将无效!!!