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); } ```