En cuanto a las señales y las ranuras, la macro Q_OBJECT
agrega una declaración de función virtual qt_metacall()
en la declaración de la clase que se definirá más tarde por el moc
. (También añade algunas declaraciones para la conversión, pero que no es demasiado importante aquí.)
El moc
continuación, lee el archivo de cabecera y cuando ve la macro, se genera otro archivo .cpp
llamado moc_headerfilename.cpp
con las definiciones de las funciones virtuales y - es posible que se haya preguntado por qué puede salirse con la suya mencionando el signals:
en su archivo de encabezado sin una definición adecuada de las señales.
Por lo tanto, cuando se invoca una señal, se ejecuta la definición del mocfile y se llama a QMetaObject::activate()
con el nombre de la señal y los argumentos de la señal. La función activate()
se da cuenta de qué conexiones se han establecido y busca los nombres para las ranuras correspondientes.
A continuación, llama qt_metacall
con los nombres de las ranuras y los argumentos dados a la señal y los delegados de función metacall esto con la ayuda de un gran switch
- case
comunicado a las ranuras reales.
Como no hay información de tiempo de ejecución real, posible en C++ en relación con los nombres reales de las señales y ranuras, como ya se ha dado cuenta, estos serán codificadas por los SIGNAL
y SLOT
macros a simples const char*
s (ya sea con "1" o "2" agregado al nombre para distinguir las señales de las ranuras).
Como se define en qobjectdefs.h
:
#define SLOT(a) "1"#a
#define SIGNAL(a) "2"#a
-
La otra cosa Q_OBJECT
la macro hace es definir las funciones tr()
dentro de su objeto que se pueden utilizar para traducir su aplicación.
Editar Como usted ha preguntado qué está haciendo qt_metacast
. Comprueba si un objeto pertenece a cierta clase y si lo hace le devuelve el puntero. Si no lo hace, devuelve 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);
Esto es necesario para proporcionar un reflejo del tiempo de ejecución que no es posible en caso contrario. La función se llama en QObject::inherits(const char *)
por ejemplo y simplemente comprueba si hay herencia.
dup: http://stackoverflow.com/questions/1406940/how-signal-and-slots-are-plplemented-under-the-hood – elcuco