什么时候应该使用 Q_OBJECT?

2021-12-09 00:00:00 qt c++ qobject

文档指出:

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

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.

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

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.

推荐答案

对于从 QObject 派生的任何非模板类,您应该使用 Q_OBJECT 宏.

You should use the Q_OBJECT macro for any non-templated classes that derive from QObject.

除了信号和槽之外,Q_OBJECT 宏提供了与给定类相关联的元对象信息.

Besides signals and slots, the Q_OBJECT macro provides the meta object information that is associated with given class.

如文档中所述:

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

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.

假设我们有以下类:

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

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

Without Q_OBJECT, the following metaobject system features (among others) will not work for Class:

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

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

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

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

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

signals - since moc won't generate their implementations and the code won't compile.

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

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 派生的类上.要将可调用项和属性添加到此类类,请改用 Q_GADGET 宏.

The Q_OBJECT macro should never be used on classes that don't derive from QObject. To add invokables and properties to such classes, use the Q_GADGET macro instead.

相关文章