C++ 什么时候应该使用 Q_OBJECT?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3689714/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
When should Q_OBJECT be used?
提问by Jake Petroules
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.
Q_OBJECT 宏必须出现在声明自己的信号和槽或使用 Qt 元对象系统提供的其他服务的类定义的私有部分中。
But exactlywhat 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.
但这究竟是什么意思?在哪些 QObject 派生类上我可以安全地省略它?如果在 QObject 派生类上省略 Q_OBJECT,然后从该类继承,会出现问题吗?基本上,我想了解更多有关何时可以从 Qt 类中省略它的信息。
采纳答案by liaK
You should use the Q_OBJECT
macro for any non-templated classes that derive from QObject
.
您应该将Q_OBJECT
宏用于从QObject
.
Besides signals and slots, the Q_OBJECT
macro provides the meta object informationthat is associated with given class.
除了信号和槽之外,Q_OBJECT
宏还提供与给定类相关联的元对象信息。
As stated in the documentation:
we strongly recommend that all subclasses of QObject use the Q_OBJECT macroregardless of whether or not they actually use signals, slots, and properties.
我们强烈建议QObject 的所有子类都使用 Q_OBJECT 宏,无论它们是否实际使用信号、槽和属性。
Suppose we have the following class:
假设我们有以下类:
class Class : public QObject {
public:
Class() {}
};
Without Q_OBJECT
, the following metaobject system features (among others) will not work for Class
:
没有Q_OBJECT
,以下元对象系统功能(以及其他功能)将不适用于Class
:
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.
qobject_cast<Class>()
- 由于缺少元数据QObject::tr()
- 由于缺少元数据slot 和 invokables 首先在 中声明
Class
,当按名称调用或查找时 - 没有任何QMetaObject
方法适用于这些方法,Qt 4 也不会connect
- 由于缺少元数据信号 - 因为
moc
不会生成它们的实现并且代码不会编译。
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 from QObject
as a matter of coding policy.
当然,您可以省略它,但是如果您曾经使用过这些功能,则需要记住将宏放入类的声明中。这是一种相当脆弱的做法,最好避免。节省的钱不值得。所以,不要等待 - 将Q_OBJECT
宏添加到每个派生自QObject
编码策略的类中。
The Q_OBJECT
macro should neverbe used on classes that don't derive from QObject
. To add invokables and properties to such classes, use the Q_GADGET
macro instead.
该Q_OBJECT
宏应该永远在不从派生类使用QObject
。要将可调用项和属性添加到此类类,请改用Q_GADGET
宏。
回答by Martin Beckett
If you want to use signals/slots you MUST include the Q_OBJECT macro and derive the class from QObject.
如果你想使用信号/插槽,你必须包含 Q_OBJECT 宏并从 QObject 派生类。
Otherwise you can leave it out, but it doesn't do any harm to include it in all the Qt gui classes
否则,您可以将其排除在外,但将其包含在所有 Qt gui 类中不会造成任何伤害
回答by Arnold Spence
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
.
嗯,第一部分很清楚,因为您可能已经知道了..信号和插槽,元对象系统的其余部分鲜为人知。也许更有用的功能之一是动态属性。虽然这些有很多用途,但我用它们来利用 Qt 的动画系统QPropertyAnimation
。
There's a little more info about the meta-object system here: http://doc.qt.io/archives/4.6/metaobjects.html
这里有更多关于元对象系统的信息: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.
我认为底线是,如果您从 QObject 层次结构继承,则无论如何都要放入 Q_OBJECT 宏。这很容易做到,并且可以避免一些潜在的令人困惑的问题。
回答by lucabox
What @liaK said is correct (in short: you shouldalways use the Q_OBJECT macro in any class that derives from QObject).
@liaK 所说的是正确的(简而言之:您应该始终在从 QObject 派生的任何类中使用 Q_OBJECT 宏)。
One thing that I haven't seen highlighted is that if you don'texplicitly put the Q_OBJECTmacro then using the sometimes very handyqobject_castwon't work!!!
我没有看到强调的一件事是,如果你没有明确地放置Q_OBJECT宏,那么使用有时非常方便的qobject_cast将不起作用!!!