2010-01-05 4 views
15

Quelqu'un peut-il m'expliquer l'idée de base des signaux Qt? & mécanisme de slots MISE EN ŒUVRE? Je veux savoir ce que font toutes ces macros Q_OBJECT "en langage C++ simple". Cette question n'est PAS sur les signaux & utilisation des emplacements.Comment Qt implémente-t-il les signaux et les slots?

ajouté: Je sais que Qt utilise le compilateur moc pour transformer Qt-C++ en C++ simple. Mais que fait moc? J'ai essayé de lire les fichiers « moc_filename.cpp », mais je ne sais pas ce qui peut quelque chose comme cela signifie

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-implemented-under-the-hood – elcuco

Répondre

16

En ce qui concerne les signaux et les emplacements, la macro Q_OBJECT ajoute une déclaration de fonction virtuelle qt_metacall() dans la déclaration de classe qui doit être définie ultérieurement par le moc. (Il ajoute également quelques déclarations de conversion, mais ce n'est pas trop important.)

Le moc lit le fichier d'en-tête et quand il voit la macro, il génère un autre fichier .cpp nommé moc_headerfilename.cpp avec les définitions aux fonctions virtuelles et - vous vous êtes peut-être demandé pourquoi vous pouviez vous en passer en mentionnant le signals: dans votre fichier d'en-tête sans une définition correcte des signaux. Ainsi, lorsqu'un signal est appelé, la définition du fichier moc est exécutée et QMetaObject::activate() est appelée avec le nom du signal et les arguments du signal. La fonction activate() détermine ensuite les connexions établies et récupère les noms des emplacements appropriés.

Ensuite, il appelle qt_metacall avec les noms de sous et les arguments donnés au signal et les délégués de la fonction metacall avec l'aide d'une grande switch - déclaration case aux emplacements réels.

Comme il n'y a pas de véritable informations d'exécution possible en C++ en ce qui concerne les noms réels pour les signaux et les machines à sous, comme cela a déjà été remarqué, ceux-ci seront codées par les SIGNAL et SLOT macros à de simples const char* s (avec « 1 » ou "2" ajouté au nom pour distinguer les signaux des slots).

Comme est défini dans qobjectdefs.h:

#define SLOT(a)  "1"#a 
#define SIGNAL(a) "2"#a 

-

L'autre chose que le fait macro Q_OBJECT est la définition des tr() fonctions à l'intérieur de votre objet qui peut être utilisé pour traduire votre application.

Modifier Comme vous avez demandé ce que fait le qt_metacast. Il vérifie si un objet appartient à certaine classe et s'il le renvoie le pointeur. Si elle ne le fait pas, il retourne 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); 

Ceci est nécessaire pour fournir une réflexion d'exécution qui n'est pas possible autrement. La fonction est appelée dans QObject::inherits(const char *) par exemple et vérifie simplement l'héritage.

+1

Consultez également ce blog pour plus de détails: http://woboq.com/blog/how-qt-signals-slots-work.html – guruz

3

Ces macros ne font absolument rien « en C plaine ++ », - ils se dilatent pour vider les chaînes (je pense) . QT utilise un compilateur de méta-objets, qui génère du code C++ pour les classes Q_OBJECT (implémentant les signaux/intervalles que vous définissez, entre autres). Vous pouvez en savoir plus sur le official documentation.

+0

En effet. En fait, si vous compilez le code, vous pouvez regarder la source produite. –

+1

Les signaux et les slots doivent avoir une petite différence lorsqu'ils sont étendus, car vous pourriez connecter le signal '' '' ('' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' – Debilski

-1

L'idée de base est que vous pouvez connecter vos objets en leur permettant d'exécuter une méthode (slot) quand un signal est fait. En effectuant la connexion ci-dessus, lorsque le pistolet émet le signal, le coureur exécutera sa fente.

Pour ce faire, vous devez déclarer vos signaux et emplacements dans vos classes respectives.

C'est l'idée de base.

Bonne chance!

+5

Mais le PO demandait à propos de la mise en œuvre interne, pas comment l'utiliser. –

+0

L'idée ressemble à ce que dojo traite avec le système de messagerie. –

Questions connexes