简体   繁体   English

什么时候应该使用 Q_OBJECT?

[英]When should Q_OBJECT be used?

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 exactly what does that mean?但这究竟是什么意思? On which QObject-derived classes can I safely omit it?在哪些 QObject 派生类上我可以安全地省略它? Will problems arise if you omit Q_OBJECT on a QObject-derived class, and then inherit from that one?如果在 QObject 派生类上省略 Q_OBJECT,然后从该类继承,会出现问题吗? Basically I would like a little more information on when I can omit it from my Qt classes.基本上,我想了解更多有关何时可以从 Qt 类中省略它的信息。

You should use the Q_OBJECT macro for any non-templated classes that derive from QObject .对于从QObject派生的任何非模板化类,您应该使用Q_OBJECT宏。

Besides signals and slots, the Q_OBJECT macro provides the meta object information that is associated with given class.除了信号和槽之外, Q_OBJECT宏还提供与给定类相关联的元对象信息

As stated in the documentation :文档所述

we strongly recommend that all subclasses of QObject use the Q_OBJECT macro regardless 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

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

  2. QObject::tr() - due to missing metadata QObject::tr() - 由于缺少元数据

  3. slots and invokables first declared in Class , when invoked or looked up by name - none of QMetaObject methods will work for these methods, neither will the Qt 4 connect - due to missing metadata slot 和 invokables 首先在Class声明,当按名称调用或查找时 - QMetaObject方法都不适用于这些方法,Qt 4 也不会connect - 由于缺少元数据

  4. signals - since moc won't generate their implementations and the code won't compile.信号 - 因为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 never be used on classes that don't derive from QObject . Q_OBJECT应用于不是从QObject派生的类。 To add invokables and properties to such classes, use the Q_GADGET macro instead.要将可调用项和属性添加到此类类,请改用Q_GADGET宏。

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 类中不会造成任何伤害

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.我认为底线是,如果您从 QObject 层次结构继承,则无论如何都要放入 Q_OBJECT 宏。 It's simple to do and will save you from some potentially baffling problems down the road.这很容易做到,并且可以避免一些潜在的令人困惑的问题。

What @liaK said is correct (in short: you should always 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't explicitly put the Q_OBJECT macro then using the sometimes very handy qobject_cast won't work!!!我没有看到强调的一件事是,如果您没有明确放置Q_OBJECT宏,那么使用有时非常方便的qobject_cast将不起作用!!!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM