El sistema de metaobjetos
El sistema de meta-objetos de Qt proporciona el mecanismo de señales y ranuras para la comunicación entre objetos, la información de tipos en tiempo de ejecución y el sistema dinámico de propiedades.
El sistema de meta-objetos se basa en tres cosas:
- La clase QObject proporciona una clase base para los objetos que pueden aprovechar el sistema de metaobjetos.
- La macro Q_OBJECT se utiliza para habilitar las características de los metaobjetos, como las propiedades dinámicas, las señales y las ranuras.
- La macro Meta-Object Compiler (
moc) proporciona a cada subclase de QObject el código necesario para implementar las características de los metaobjetos.
La herramienta moc lee un archivo fuente C++. Si encuentra una o más declaraciones de clase que contengan la macro Q_OBJECT, genera otro archivo fuente C++ que contiene el código meta-objeto para cada una de esas clases. Este archivo fuente generado se integra en el archivo fuente de la clase a través de #include o, lo que es más habitual, se compila y enlaza con la implementación de la clase.
Además de proporcionar el mecanismo de señales y ranuras para la comunicación entre objetos (la principal razón para introducir el sistema), el código de metaobjetos proporciona las siguientes características adicionales:
- QObject::metaObject() devuelve el meta-object asociado a la clase.
- QMetaObject::className() devuelve el nombre de la clase en forma de cadena en tiempo de ejecución, sin necesidad de que el compilador de C++ ofrezca soporte nativo de información de tipos en tiempo de ejecución (RTTI).
- QObject::inheritsLa función () devuelve si un objeto es una instancia de una clase que hereda una clase especificada dentro del árbol de herencia QObject.
- QObject::tr() traduce cadenas para su internacionalización.
- QObject::setProperty() y QObject::property() establecen y obtienen dinámicamente propiedades por nombre.
- QMetaObject::newInstance() construye una nueva instancia de la clase.
También es posible realizar transformaciones dinámicas utilizando qobject_cast() en las clases QObject. La función qobject_cast() se comporta de forma similar a la función estándar de C++ dynamic_cast(), con la ventaja de que no requiere soporte RTTI y funciona a través de los límites de las bibliotecas dinámicas. Intenta convertir su argumento al tipo de puntero especificado entre paréntesis angulares, devolviendo un puntero distinto de cero si el objeto es del tipo correcto (determinado en tiempo de ejecución), o nullptr si el tipo del objeto es incompatible.
Por ejemplo, supongamos que MyWidget hereda de QWidget y se declara con la macro Q_OBJECT:
QObject *obj = new MyWidget;
La variable obj, de tipo QObject *, se refiere en realidad a un objeto MyWidget, por lo que podemos convertirla adecuadamente:
La conversión de QObject a QWidget tiene éxito, porque el objeto es en realidad un MyWidget, que es una subclase de QWidget. Como sabemos que obj es un MyWidget, también podemos convertirlo en MyWidget *:
MyWidget *myWidget = qobject_cast<MyWidget *>(obj);
La conversión a MyWidget es correcta porque qobject_cast() no distingue entre tipos Qt incorporados y tipos personalizados.
La conversión a QLabel, por otro lado, falla. El puntero se establece entonces en nullptr. Esto hace posible manejar objetos de diferentes tipos de forma diferente en tiempo de ejecución, basándose en el tipo:
if (QLabel *label = qobject_cast<QLabel *>(obj)) { label->setText(tr("Ping")); } else if (QPushButton *button = qobject_cast<QPushButton *>(obj)) { button->setText(tr("Pong!")); }
Aunque es posible utilizar QObject como clase base sin la macro Q_OBJECT y sin código de meta-objeto, ni las señales y ranuras ni las demás características descritas aquí estarán disponibles si no se utiliza la macro Q_OBJECT. Desde el punto de vista del sistema de meta-objetos, una subclase QObject sin meta-código es equivalente a su ancestro más cercano con meta-código de objeto. Esto significa, por ejemplo, que QMetaObject::className() no devolverá el nombre real de su clase, sino el nombre de clase de este ancestro.
Por lo tanto, recomendamos encarecidamente que todas las subclases de QObject utilicen la macro Q_OBJECT independientemente de si realmente utilizan o no señales, ranuras y propiedades.
Ver también QMetaObject, Sistema de Propiedades de Qt, y Señales y Slots.
© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.