什么时候应该使用Q_OBJECT?

发布于 2024-09-18 15:34:09 字数 235 浏览 8 评论 0原文

该文档指出:

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

寂寞清仓 2024-09-25 15:34:09

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

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

文档中所述:

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

假设我们有以下类:

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

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

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

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

  3. 在按名称调用或查找时首先在Class中声明的槽和可调用对象- QMetaObject 方法都不适用于这些方法,Qt 4 connect 也不会 - 由于缺少元数据

  4. signals - 因为 moc 不会生成它们的实现,并且代码也不会编译。

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

Q_OBJECT决不用在不是从 QObject 派生的类上。要向此类类添加可调用项和属性,请改用 Q_GADGET 宏。

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

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

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.

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:

  1. qobject_cast<Class>() - due to missing metadata

  2. QObject::tr() - due to missing metadata

  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

  4. signals - 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 from QObject as a matter of coding policy.

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.

勿挽旧人 2024-09-25 15:34:09

如果你想使用信号/槽,你必须包含 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

爱,才寂寞 2024-09-25 15:34:09

嗯,第一部分非常清楚,您可能已经知道了......信号和槽,元对象系统的其余部分不太为人所知。也许更有用的功能之一是动态属性。尽管它们有很多用途,但我使用它们是为了利用 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.

独孤求败 2024-09-25 15:34:09

@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!!!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文