什么时候应该使用Q_OBJECT?
该文档指出:
Q_OBJECT 宏必须出现在 类定义的私有部分 声明自己的信号并且 插槽或使用其他服务 由 Qt 的元对象系统提供。
但这到底是什么意思呢?在哪些 QObject 派生类上我可以安全地省略它?如果在 QObject 派生类上省略 Q_OBJECT,然后从该类继承,会出现问题吗?基本上我想要更多关于何时可以从 Qt 类中省略它的信息。
The documentation states that:
The Q_OBJECT macro must appear in the
private section of a class definition
that declares its own signals and
slots or that uses other services
provided by Qt's meta-object system.
But exactly what does that mean? On which QObject-derived classes can I safely omit it? Will problems arise if you omit Q_OBJECT on a QObject-derived class, and then inherit from that one? Basically I would like a little more information on when I can omit it from my Qt classes.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
对于从
QObject
派生的任何非模板化类,您应该使用Q_OBJECT
宏。除了信号和槽之外,
Q_OBJECT
宏还提供与给定类关联的元对象信息。如文档中所述:
假设我们有以下类:
如果没有
Q_OBJECT
,以下元对象系统功能(以及其他功能)将不适用于Class
:qobject_cast( )
- 由于缺少元数据QObject::tr()
- 由于缺少元数据在按名称调用或查找时首先在
Class
中声明的槽和可调用对象-QMetaObject
方法都不适用于这些方法,Qt 4connect
也不会 - 由于缺少元数据signals - 因为
moc
不会生成它们的实现,并且代码也不会编译。当然,您可以省略它,但如果您曾经使用过这些功能,则需要记住将宏放入类的声明中。这是一种相当脆弱的做法,最好避免。节省的钱不值得。因此,不要等待 - 根据编码策略,将
Q_OBJECT
宏添加到从QObject
派生的每个类中。Q_OBJECT
宏决不用在不是从QObject
派生的类上。要向此类类添加可调用项和属性,请改用Q_GADGET
宏。You should use the
Q_OBJECT
macro for any non-templated classes that derive fromQObject
.Besides signals and slots, the
Q_OBJECT
macro provides the meta object information that is associated with given class.As stated in the documentation:
Suppose we have the following class:
Without
Q_OBJECT
, the following metaobject system features (among others) will not work forClass
:qobject_cast<Class>()
- due to missing metadataQObject::tr()
- due to missing metadataslots and invokables first declared in
Class
, when invoked or looked up by name - none ofQMetaObject
methods will work for these methods, neither will the Qt 4connect
- due to missing metadatasignals - since
moc
won't generate their implementations and the code won't compile.You can omit it, of course, but if you ever use these features, you'll need to remember to put the macro into the class's declaration. This is a rather brittle practice and best avoided. The savings are not worth it. So, don't wait - add the
Q_OBJECT
macro to every class that derives fromQObject
as a matter of coding policy.The
Q_OBJECT
macro should never be used on classes that don't derive fromQObject
. To add invokables and properties to such classes, use theQ_GADGET
macro instead.如果你想使用信号/槽,你必须包含 Q_OBJECT 宏并从 QObject 派生类。
否则你可以忽略它,但是将它包含在所有 Qt gui 类中也没有任何坏处
If you want to use signals/slots you MUST include the Q_OBJECT macro and derive the class from QObject.
Otherwise you can leave it out, but it doesn't do any harm to include it in all the Qt gui classes
嗯,第一部分非常清楚,您可能已经知道了......信号和槽,元对象系统的其余部分不太为人所知。也许更有用的功能之一是动态属性。尽管它们有很多用途,但我使用它们是为了利用 Qt 的动画系统
QPropertyAnimation
。这里有关于元对象系统的更多信息: http://doc.qt .io/archives/4.6/metaobjects.html
我认为底线是,如果您从 QObject 层次结构继承,则无论如何都要放入 Q_OBJECT 宏。这样做很简单,并且可以让您避免日后出现一些潜在的令人困惑的问题。
Well the first part is pretty clear as you probably already know.. signals and slots, the rest of the Meta-object system is a little lesser known. Perhaps one of the more useful features is dynamic properties. Although these have many uses, I used them to take advantage of Qt's animation system
QPropertyAnimation
.There's a little more info about the meta-object system here: http://doc.qt.io/archives/4.6/metaobjects.html
I think the bottom line is, if you inherit from the QObject hierarchy, throw in the Q_OBJECT macro regardless. It's simple to do and will save you from some potentially baffling problems down the road.
@liaK 所说的是正确的(简而言之:您应该始终在从 QObject 派生的任何类中使用 Q_OBJECT 宏)。
我没有看到突出显示的一件事是,如果您没有明确放置Q_OBJECT宏,那么使用有时非常方便 qobject_cast 不起作用!
What @liaK said is correct (in short: you should always use the Q_OBJECT macro in any class that derives from QObject).
One thing that I haven't seen highlighted is that if you don't explicitly put the Q_OBJECT macro then using the sometimes very handy qobject_cast won't work!!!