How does Qt implement signals and slots?

qt, signals-slots

Solution

Concerning the signals and slots, the `Q_OBJECT` macro adds a virtual function `qt_metacall()` declaration into the class’s declaration which is to be defined later by the the `moc`. (It also adds some declarations for conversion but that’s not too important here.)

The `moc` then reads the header file and when it sees the macro, it generates another `.cpp` file named `moc_headerfilename.cpp` with the definitions to the virtual functions and – you might have asked yourself why you can get away with mentioning the `signals:` in your header file without a proper definition – of the signals.

So, when a signal is called, the definition from the mocfile is executed and `QMetaObject::activate()` is called with the signal’s name and the signal’s arguments. The `activate()` function then figures out which connections have been established and fetches the names for the appropriate slots.

Then it calls `qt_metacall` with the slot names and the arguments given to the signal and the metacall function delegates this with the help of a large `switch`—`case` statement to the real slots.

As there is no real runtime information possible in C++ concerning the actual names for the signals and slots, as has already been noticed, these will be encoded by the `SIGNAL` and `SLOT` macros to simple `const char*`s (with either "1" or "2" added to the name to distinguish signals from slots).

As is defined in `qobjectdefs.h`:

#define SLOT(a)     "1"#a
#define SIGNAL(a)   "2"#a

The other thing the `Q_OBJECT` macro does is defining the `tr()` functions inside your object which can be used to translate your application.

Edit As you asked what the `qt_metacast` is doing. It checks whether an object belongs to certain class and if it does returns the pointer to it. If it doesn’t, it returns 0.

Widget* w = new Widget();
Q_ASSERT(w->qt_metacast("Widget") != 0);
Q_ASSERT(w->qt_metacast("QWidget") != 0);
Q_ASSERT(w->qt_metacast("QObject") != 0);
Q_ASSERT(w->qt_metacast("UnrelatedClass") == 0);

This is needed to provide some runtime reflection which is not possible otherwise. The function is called in `QObject::inherits(const char *)` for example and simply checks for inheritance.

Problem

Can someone explain to me the basic idea of Qt signals&slots mechanism IMPLEMENTATION? I want to know what all those Q_OBJECT macros do "in plain C++". This question is NOT about signals&slots usage. added: I know that Qt uses moc compiler to transform Qt-C++ in plain C++. But what does moc do? I tried to read "moc_filename.cpp" files but I have no idea what can something like this mean ``` void *Widget::qt_metacast(const char *_clname) { if (!_clname) return 0; if (!strcmp(_clname, qt_meta_stringdata_Widget)) return static_cast<void*>(const_cast< Widget*>(this)); return QDialog::qt_metacast(_clname); } ```

Original source

Related problems