54

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.

László Papp
  • 51,870
  • 39
  • 111
  • 135
Jake Petroules
  • 23,472
  • 35
  • 144
  • 225
  • 1
    Short answer: You can omit `Q_OBJECT` when you do not need any of the services it offers (signals, slots, meta-object information). If you decide to use the `Q_OBJECT`-macro, it must appear in the private section of a class' definition. This is not a requirement of the macro itself, but rather a consequence of its implementation: Its final expression is `private:`. Also, don't bother reading [liaK's answer](http://stackoverflow.com/a/3689807/1889329). Here's a summary: "Yes, I mean, no. Or?" – IInspectable Jun 25 '14 at 14:55

4 Answers4

43

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.

cgmb
  • 4,284
  • 3
  • 33
  • 60
liaK
  • 11,422
  • 11
  • 48
  • 73
  • 1
    It is worthwhile to note that you MUST put the actual text "Q_OBJECT" in that file, in other words, you can't have a macro that in-turn contains the Q_OBJECT macro, at least not in a separate file, which is the usual case for macros. The meta-object compiler (moc) looks for the text in the classes directly, so it would get confused and try to compile your file that contains the macro instead of the place you are using the macro (which would probably lead to errors at link time). – osirisgothra Jan 30 '14 at 16:14
  • 1
    Weird. First you claim that using `Q_OBJECT` is **mandatory** for any class deriving from `QObject`, only to move on to quote a section from the documentation that states the opposite (i.e. it is **optional**). Please update your answer to remove the ambiguity. – IInspectable Jun 25 '14 at 10:34
  • `Actually, you have to use Q_OBJECT macro, for any classes that you derive from QObject.` -> That is wrong IMHO, if you do not use signals, slots, properties, qobject_cast and those Q_OBJECT features, just regular QObject things, it is a superfluous overhead. – László Papp Nov 01 '14 at 09:10
  • Some example code from Qt contradicts the statement `you have to use Q_OBJECT macro, for any classes that you derive from QObject`: http://doc.qt.digia.com/qq/qq15-academic.html#connectingtotemplates "If the signals and slots don't require the template parameter to be part of the prototype, the workaround is to make a template class inherit a QObject subclass that provides the required signals and slots" -- this class does **not** use the `Q_OBJECT` macro. – Cuadue Nov 17 '14 at 17:27
  • @liaK if we are not using qmake but we want to use the slot and or signal system because we have a class that inherits from QObject how can I supplement what the Q_OBJECT macro and lack of using qmake? Do I just call moc on my object or is it a lot more involved? – simgineer Jan 18 '19 at 01:45
5

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

Martin Beckett
  • 94,801
  • 28
  • 188
  • 263
  • `QObject::tr` is not a signals/slots mechanism, but I've just fixed its malfunction in my code due to missing `Q_OBJECT` in the `QObject` derivative that called this method. – Ruslan Mar 03 '20 at 11:06
4

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.

Christophe Weis
  • 2,518
  • 4
  • 28
  • 32
Arnold Spence
  • 21,942
  • 7
  • 74
  • 67
2

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

Christophe Weis
  • 2,518
  • 4
  • 28
  • 32
lucabox
  • 113
  • 6