It is also possible to perform dynamic casts using qobject_cast() on QObject classes. The qobject_cast() function behaves similarly to the standard C++ dynamic_cast(), with the advantages that it doesn't require RTTI support and it works across dynamic library boundaries. It attempts to cast its argument to the pointer type specified in angle-brackets, returning a non-zero pointer if the object is of the correct type (determined at run-time), or 0 if the object's type is incompatible.
For example, let's assume MyWidget inherits from QWidget and is declared with the Q_OBJECT macro:
QObject *obj = new MyWidget;
The obj variable, of type QObject *, actually refers to a MyWidget object, so we can cast it appropriately:
QWidget *widget = qobject_cast<QWidget *>(obj);
The cast from QObject to QWidget is successful, because the object is actually a MyWidget, which is a subclass of QWidget. Since we know that obj is a MyWidget, we can also cast it to MyWidget *:
MyWidget *myWidget = qobject_cast<MyWidget *>(obj);
The cast to MyWidget is successful because qobject_cast() makes no distinction between built-in Qt types and custom types.
QLabel *label = qobject_cast<QLabel *>(obj);
The cast to QLabel, on the other hand, fails. The pointer is then set to 0. This makes it possible to handle objects of different types differently at run-time, based on the type:
if (QLabel *label = qobject_cast<QLabel *>(obj)) {
label->setText(tr("Ping"));
} else if (QPushButton *button = qobject_cast<QPushButton *>(obj)) {
button->setText(tr("Pong!"));
}
While it is possible to use QObject as a base class without the Q_OBJECT macro and without meta-object code, neither signals and slots nor the other features described here will be available if the Q_OBJECT macro is not used. From the meta-object system's point of view, a QObject subclass without meta code is equivalent to its closest ancestor with meta-object code. This means for example, that QMetaObject::className() will not return the actual name of your class, but the class name of this ancestor.
Therefore, 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.
See also QMetaObject, Qt's Property System, and Signals and Slots.