CopperSpice API  1.7.2
Meta Object System

The meta object system provides the signal and slot mechanism for communication between objects, run-time type information, and the dynamic property system. The QObject class is the base class for objects which use the meta object system. To use the meta object system you must add the CS_OBJECT() macro inside the private section of the class declaration.

In addition to providing the Signals and Slots mechanism for communication between objects the meta object system provides the following additional features:

  • QObject::metaObject() returns the corresponding meta object for that class
  • QMetaObject::className() returns the class name as a string at run-time
  • QObject::inherits(const QString &className) returns whether an object inherits from className
  • QObject::tr() translate strings for Internationalization
  • QObject::setProperty() and QObject::property() dynamically set and get properties by name
  • QMetaObject::newInstance() constructs a new instance of the specified class

It is also possible to perform dynamic casts using qobject_cast() on QObject classes. For example, given MyWidget inherits from QWidget and is declared with the CS_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 CopperSpice types and custom types.

QLabel *label = qobject_cast<QLabel *>(obj);
// label is 0

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 data 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 CS_OBJECT() macro and without meta object code, neither signals, slots nor the other features described here will be available if the CS_OBJECT() macro is not used. This means the QMetaObject::className() will not return the actual name of your class, but the class name of this ancestor.

We recommend all subclasses of QObject use the CS_OBJECT() macro regardless of whether or not they actually use signals, slots, and properties.

See also
QMetaObject, Property System, and Signals and Slots