Disons que j'ai ce signal:
signals:
void progressNotification(int progress);
Je n'ai appris que récemment sur le mot-clé emit dans Qt. Jusqu'à présent, j'exécutais des signaux en les appelant simplement comme une fonction normale. Donc au lieu de:
emit progressNotification(1000 * seconds);
Je souhaiterai écrire:
progressNotification(1000 * seconds);
Les appeler comme ça semblait fonctionner, et tous les slots connectés s'exécuteraient, l'utilisation du mot-clé emit provoquait-elle un comportement différent, ou est-ce juste du sucre syntaxique?
emit
n'est pas nécessaire. C'est étrange cependant que vous ayez apprisemit
longtemps après avoir appelé directement les signaux, car le système de créneaux de signaux est l'une des premières choses à apprendre sur Qt.Réponses:
emit
est juste du sucre syntaxique. Si vous regardez la sortie pré-traitée de la fonction qui émet un signal, vous verrez qu'elleemit
est juste partie.La "magie" se produit dans le code généré pour la fonction d'émission de signal, que vous pouvez regarder en inspectant le code C ++ généré par moc.
Par exemple, un
foo
signal sans paramètre génère cette fonction membre:Et le code
emit foo();
est pré-traité pour simplementfoo();
emit
est défini dansQt/qobjectdefs.h
(dans la version open-source de la source de toute façon), comme ceci:(La garde de définition est de vous permettre d'utiliser Qt avec d'autres frameworks qui ont des noms en collision via l'
no_keywords
option de configuration QMake.)la source
emit
qui a fait plus que rien? Je trouve que le fait d'avoir le 'sucre syntaxique' dans ce cas ne fait que confondre le novice (ou du moins moi quand j'étais un utilisateur novice de Qt) - il semble que quelque chose de magique ou d'important se passe avec leemit
pseudo-mot-clé, quand il ne fait rien à all - toute la magie se produit dans une ancienne fonction régulière quimoc
crée (moc
c'est la magie pour les signaux et les slots Qt).emit
est une décoration inutile qui ne fait que paraître importante.emit
indique à la personne qui lit l'appel que la magie est sur le point de se produire (c'est-à-dire que cela va déclencher du code dans des objets dont cette classe n'a potentiellement jamais entendu parler, et que ces appels peuvent être synchrones ou asynchrones), ce qui est essentiellement totalement perdu si vous omettez le mot-clé. Utilise le. C'est une documentation automatique. Les "novices" devraient lire les documents et les tutoriels, etemit
sont toujours là (dans les documents officiels de toute façon). Découvrir que vous pouvez simplement appeler la fonction devrait se produire après avoir "vu la lumière" - vous n'êtes plus un novice à ce stade.emit
"mot-clé". Je pense que j'aurais préféré qu'une convention de dénomination soit utilisée s'il était nécessaire de préciser qu'un appel de fonction est un signal.emit
.emit
psuedo-keyword-comment était de préciser qu'un signal est appelé, alors une convention de dénomination pourrait faire de même, sans mystère et avec des avantages similaires. La convention de dénomination ne peut pas être appliquée par Qt (en fait,moc
pourrait l'appliquer - mais je ne le préconise pas non plus), mais Qt ne peut pas imposer l'utilisation de l'unemit
ou l'autre. Et bien que vous puissiez `` désactiver ''emit
s'il y a un conflit de nom, cela n'aide pas beaucoup si vous avez un tas de fichiers source qui l'utilisent (inutilement, pour démarrer).Après 18 mois ... j'ai commencé par des commentaires sous la réponse de @ Mat, et je manquais rapidement de place. Ainsi la réponse.
IMO
emit
n'est ni un sucre syntaxique ni un simple mot-clé dans le sens oùconnect
mécanisme à reconnaître qu'il s'agit effectivement d'unsignal
, etL'ensemble du système signal / slot est un idiome différent d'un simple appel de fonction. Je crois que cela découle du modèle d'observateur. Il y a aussi une différence majeure entre a
signal
et aslot
: un signal n'a pas à être implémenté, alors qu'un slot doit l'être !Vous marchez dans la rue et voyez une maison en feu (un signal). Vous composez le 911 ( connectez le signal d'incendie à l'emplacement de réponse 911 ). Le signal n'a été émis que tandis que le créneau a été mis en œuvre par les pompiers. Peut-être imprécis, mais vous voyez l'idée. Regardons l'exemple de OP.
Certains objets backend savent combien de progrès ont été réalisés. Donc, cela pourrait simplement
emit progressNotification(...)
signaler. C'est à la classe qui affiche la barre de progression réelle, de capter ce signal et de l'exécuter. Mais comment la vue se connecte-t-elle à ce signal? Bienvenue dans le système signal / slot de Qt. On peut maintenant concevoir une classe de gestionnaire (typiquement un widget de sortes), qui se compose d'un objet de vue et d'un objet de calcul de données (les deux étantQObjects
), peut fonctionnerconnect (m_myDataEngine, &DataEngine::progressNotification, m_myViewObj, &SimpleView::displayProgress)
.N'entrons pas dans les aspects de conception de la classe de gestionnaire, mais il suffit de dire que c'est là que le système signal / slot brille. Je peux me concentrer sur la conception d'une architecture très propre pour mon application. Pas toujours, mais souvent, je trouve que j'émets simplement des signaux mais que j'implémente des slots .
S'il est possible d'utiliser / d'appeler une méthode de signal sans jamais l'émettre , cela implique nécessairement que vous n'avez jamais eu besoin de cette fonction comme signal en premier lieu.
la source
emit
n'est en effet qu'une macro vide et purement facultative. Ce n'est pas le cas des mots-cléssignal
etslot
qui sont traités par le moc.signal
est utilisé pour fournir l'implémentation de la fonction,slot
est utilisé pour créer l'entrée de méta-objet afin qu'il soit trouvé avec laSLOT(MySlot())
macro ou dans QML.emit
est un suggestion syntaxique. Rien ne se plaindra jamais si vous écrivezemit i++;
(mais peut-être vos collègues) et que vous ne pouvez toujours pas vous connecteri++
.La seconde option impliquerait que vous sachiez toujours quel est le nom de la fonction et les paramètres de la fonction et que l'objet auquel vous l'envoyez est connu par cette fonction particulière. Ces deux cas ne sont pas toujours vrais, ce sont donc les deux principales raisons pour lesquelles des créneaux et des signaux ont été créés. "sous le capot", le mécanisme de signal et de fente n'est qu'un tableau avec des pointeurs vers chaque fonction connectée.
Regardez également ce pdf qui explique très clairement la nature du mécanisme des signaux et des slots: http://www.elpauer.org/stuff/a_deeper_look_at_signals_and_slots.pdf
la source
emit
c'était juste un no-op. Mais même dans ce cas, la lecture du corps de la question aurait dû éclaircir les choses, donc -1.