2010-01-05 24 views
15

¿Puede alguien explicarme la idea básica de las señales Qt & mecanismo de ranuras IMPLEMENTACIÓN? Quiero saber qué hacen todas esas macros Q_OBJECT "en C++ simple". Esta pregunta NO es sobre señales & uso de ranuras.¿Cómo implementa Qt señales y ranuras?

añadido: Sé que Qt usa el compilador de moc para transformar Qt-C++ en C++. Pero, ¿qué hace moc? Traté de leer archivos "moc_filename.cpp" pero no tengo ni idea de lo que puede significar algo como esto

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); 
} 
+0

dup: http://stackoverflow.com/questions/1406940/how-signal-and-slots-are-plplemented-under-the-hood – elcuco

Respuesta

16

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.

+1

Consulte también esta publicación en el blog para obtener más información: http://woboq.com/blog/how-qt-signals-slots-work.html – guruz

3

Esos macros hacer absolutamente nada "en la llanura C++", - se expanden para vaciar cuerdas (creo) .

QT usa un compilador de metaobjetos que genera el código C++ para las clases Q_OBJECT habilitadas (implementando las señales/ranuras que defina, entre otras cosas).

Puede leer más al respecto en el official documentation.

+0

De hecho. De hecho, si compila el código, puede ver la fuente producida. –

+1

Las señales y las ranuras deben tener una pequeña diferencia cuando se expanden como podría 'conectar()' señal a la señal y entonces no estaría claro qué significa la cadena. – Debilski

-1

La idea básica es que puede conectar sus objetos permitiéndoles ejecutar un método (ranura) cuando se hace una señal.

connect(pistol,SIGNAL(sigShoot()),runner,SLOT(slotRun())) 

Realizando la conexión anterior, cuando la pistola emita la señal, el corredor ejecutará su ranura.

Para hacer esto, debe declarar sus señales y ranuras en sus respectivas clases.

Es la idea básica.

¡Buena suerte!

+5

Pero el OP preguntaba sobre la implementación interna, no cómo usarla. –

+0

La idea se parece a lo que dojo trata con el sistema de mensajes. –

Cuestiones relacionadas