I just started using Qt and noticed that all the example class definitions have the macro Q_OBJECT
as the first line. What is the purpose of this preprocessor macro?

- 95,931
- 16
- 151
- 313

- 18,164
- 32
- 127
- 177
6 Answers
From the Qt documentation:
The Meta-Object Compiler, moc, is the program that handles Qt's C++ extensions.
The moc tool reads a C++ header file. If it finds one or more class declarations that contain the Q_OBJECT macro, it produces a C++ source file containing the meta-object code for those classes. Among other things, meta-object code is required for the signals and slots mechanism, the run-time type information, and the dynamic property system.

- 95,931
- 16
- 151
- 313

- 11,510
- 1
- 38
- 59
-
why don't I need to explicity write `Q_OBJECT::connect()` but rather just `connect()`? – mLstudent33 May 31 '20 at 19:41
-
2@mLstudent33 You can write QObject::connect() if you want. – Patapoom Jun 30 '21 at 13:20
It simply tells the pre-compiler that this class needs to be run through the 'moc', or Meta-Object Compiler, which adds extra hidden fields and functions to the class as well as parsing signals and slots. You only need to add this to classes that use the signal/slot mechanism or other Qt class-level features, such as introspection. You do not need to add Q_OBJECT to classes that only use standard C++ features.

- 12,292
- 8
- 41
- 69

- 94,801
- 28
- 188
- 263
-
4It's also false that you only need it on classes that use the signal/slot mechanism. The absence of `Q_OBJECT` breaks the `qobject_cast` and introspection. It can lead to some perplexing behavior, so it's a bad idea. – Kuba hasn't forgotten Monica Apr 07 '16 at 20:39
-
4It's not true that `Q_OBJECT` will be "quietly" ignored in any other (non-`QObject`) classes. According to the C++ standard, it introduces undefined behavior by declaring several member functions and variables that never get defined. It also pollutes your class's namespace with `QObject`-specific members. E.g. a `Q_OBJECT` may well break an unrelated class that happens to contain a method called `metaObject`. – Kuba hasn't forgotten Monica Apr 07 '16 at 20:44
-
2That's wrong. Though you probably want to equip most gui-classes with the `Q_OBJECT` macro, it makes perfectly sense to have non-gui-classes with the macro, as well as gui-classes without the macro. The macro is useful, but neither limited to nor required for gui-classes. – pasbi Dec 06 '18 at 19:22
The MOC (meta object compiler) converts the Q_OBJECT macro included header files in to C++ equivalent source code. It basically controls the signal-slot mechanism, and makes it understandable to the C++ compiler

- 14,133
- 7
- 40
- 79

- 85
- 1
- 1
-
2That is false: the `Q_OBJECT` macro is expanded by the compiler, moc is not needed for that. The moc does not do anything with the macro itself, but it generates the **definitions** of the member variables and methods that the `Q_OBJECT` macro has **declared**. – Kuba hasn't forgotten Monica Apr 07 '16 at 20:46
1 From Qt documentation of The Meta-Object System
The moc tool reads a C++ source file. If it finds one or more class declarations that contain the Q_OBJECT macro, it produces another C++ source file which contains the meta-object code for each of those classes. This generated source file is either #include'd into the class's source file or, more usually, compiled and linked with the class's implementation.
2 From Qt documentation of THE Q_OBJECT
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.
3 From Qt documentation of moc
The moc tool reads a C++ header file. If it finds one or more class declarations that contain the Q_OBJECT macro, it produces a C++ source file containing the meta-object code for those classes. Among other things, meta-object code is required for the signals and slots mechanism, the run-time type information, and the dynamic property system.
4 From Qt documentation of Signals and Slots
The Q_OBJECT macro is expanded by the preprocessor to declare several member functions that are implemented by the moc; if you get compiler errors along the lines of "undefined reference to vtable for LcdNumber", you have probably forgotten to run the moc or to include the moc output in the link command.

- 63
- 1
- 5
In gcc with -E
you can see expanded macros. This is what Q_OBJECT
expands into on gcc on Linux. Be aware, this might be platform dependent and it might change depending on the version of QT. You can see it is not just a tag for the moc compiler.
# 11 "mainwindow.hh"
#pragma GCC diagnostic push
# 11 "mainwindow.hh"
# 11 "mainwindow.hh"
#pragma GCC diagnostic ignored "-Wsuggest-override"
# 11 "mainwindow.hh"
static const QMetaObject staticMetaObject; virtual const QMetaObject *metaObject() const; virtual void *qt_metacast(const char *); virtual int qt_metacall(QMetaObject::Call, int, void **); static inline QString tr(const char *s, cons
t char *c = nullptr, int n = -1) { return staticMetaObject.tr(s, c, n); } __attribute__ ((__deprecated__)) static inline QString trUtf8(const char *s, const char *c = nullptr, int n = -1) { return staticMetaObject.tr(s, c, n); } private:
# 11 "mainwindow.hh"
#pragma GCC diagnostic ignored "-Wattributes"
# 11 "mainwindow.hh"
__attribute__((visibility("hidden"))) static void qt_static_metacall(QObject *, QMetaObject::Call, int, void **);
# 11 "mainwindow.hh"
#pragma GCC diagnostic pop
# 11 "mainwindow.hh"
struct QPrivateSignal {};

- 7,921
- 9
- 48
- 66
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.

- 17
- 4
-
2This is misleading: The `Q_OBJECT` macro must appear in every class that derives from `QObject`. Your code will be subtly broken when the macro is absent, and just because it happens to compile doesn't make it OK. – Kuba hasn't forgotten Monica Apr 07 '16 at 20:47
-
2If you look at the implementation of `Q_OBJECT`, you'd find that it uses access specifiers. So whether the macro should appear in under the `private`, `protected`, or `public` specifiers is irrelevant – it's just convention to place it at the head of the class. – TrebledJ Apr 05 '19 at 18:46