Qt événements et de signaux/slots
De l'intervalle Qt monde, quelle est la différence d'événements et de signaux/slots?
- T-on remplacer l'autre? Sont des événements d'une abstraction de signal/slots?
Vous devez vous connecter pour publier un commentaire.
La Documentation de Qt explique sans doute le mieux:
Donc, les événements et les signaux/slots sont deux mécanismes parallèles accomplir les mêmes choses. En général, un événement est généré par un organisme extérieur (par exemple, le clavier ou la molette de la souris) et sera livré par la boucle d'événements dans
QApplication
. En général, sauf si vous configurez le code, vous ne serez pas générer des événements. Vous pouvez les filtrer parQObject::installEventFilter()
ou de gérer les événements en sous-classé objet en substituant les fonctions appropriées.Les signaux et les Slots sont beaucoup plus faciles à générer et de recevoir et vous pouvez connecter deux
QObject
sous-classes. Ils sont gérés par le biais de la Métaclasse (jetez un oeil à votre moc_classname.cpp fichier pour plus de détails), mais la plupart des interclasses de communication que vous produirez sera probablement utiliser les signaux et les slots. Les signaux peuvent se livrer immédiatement ou en différé, via une file d'attente (si vous êtes à l'aide de threads).Un signal peut être généré.
Dans Qt, de signaux et événements sont à la fois les implémentations de la Modèle observateur. Ils sont utilisés dans des situations différentes, parce qu'ils ont des forces et des faiblesses.
Tout d'abord nous allons définir ce que nous entendons par "événement de Qt' exactement: une fonction virtuelle dans une classe Qt, qui vous êtes attendus à ré-écrire dans une classe de base de la vôtre si vous souhaitez gérer l'événement. C'est lié à la Méthode de modèle de modèle.
Remarque comment j'ai utilisé le mot "poignée". Ici, en effet, une différence fondamentale entre l'intention de signaux et événements:
La différence est que lorsque vous "traiter" le cas, vous prenez la responsabilité de "répondre" à un comportement qui est utile à l'extérieur de la classe. Par exemple, considérons une application qui a un bouton avec un numéro dessus. L'application doit permettre à l'utilisateur de se concentrer sur le bouton et de modifier le numéro en appuyant sur les boutons "haut" et "bas" de votre clavier. Sinon, le bouton doit fonctionner comme une normale
QPushButton
(il peut être cliqué, etc). Dans Qt ceci est fait par la création de votre propre petit réutilisables "composant" (sous-classe deQPushButton
), qui reimplementsQWidget::keyPressEvent
. Pseudo:Voir? Ce code présente une nouvelle abstraction: un widget qui agit comme un bouton, mais avec quelques fonctionnalités supplémentaires. Nous avons ajouté cette fonctionnalité très commodément:
keyPressEvent
un signal, nous aurions besoin de décider si hériterQPushButton
ou juste à l'extérieur de connecter le signal. Mais ce serait stupide, puisque dans Qt vous êtes toujours devrait hériter lors de l'écriture d'un widget avec un comportement personnalisé (pour une bonne raison - de la possibilité de réutilisation/modularité). Donc, en faisantkeyPressEvent
un événement, ils expriment leur intention dekeyPressEvent
est juste un bloc de construction de base de la fonctionnalité. Si c'était un signal, il aurais l'air d'un utilisateur face chose, quand il n'est pas destiné à être.keyPressEvent
ont été un signal.La conception de l'intervalle Qt est bien pensé - et ils nous ont fait tomber dans la fosse de succès par il est facile de faire la bonne chose et difficile de faire la mauvaise chose (en faisant événement keypressevent un événement).
D'autre part, envisager l'utilisation la plus simple de
QPushButton
- juste de l'instanciation, et averti lorsqu'il est cliqué:C'est censé être fait par le utilisateur de la classe:
QPushButton
chaque fois que nous voulons que le bouton pour nous aviser d'un clic, qui nécessiterait beaucoup de sous-classes pour aucune bonne raison! Un widget qui affiche toujours un "Hello world"messagebox
lorsque l'utilisateur clique dessus n'est utile que dans un seul cas - il est donc totalement non réutilisables. Encore une fois, nous n'avons pas le choix, mais de faire la bonne chose - en se connectant à l'extérieur.clicked()
- ou de connecter plusieurs signaux àsayHello()
. Avec des signaux il n'y a pas de chichi. Avec sous-classement, vous auriez à vous asseoir et de réfléchir à certains diagrammes de classes jusqu'à ce que vous décidez sur une conception appropriée.Noter que l'un des endroits les
QPushButton
émetclicked()
est dans sonmousePressEvent()
mise en œuvre. Cela ne veut pas direclicked()
etmousePressEvent()
sont interchangeables - seulement qu'ils sont liés.Afin de signaux et événements ont des finalités différentes (mais sont liées en ce que les deux vous permettent de vous abonner à une notification de quelque chose qui se passe).
Je n'aime pas les réponses. – Permettez-moi de me concentrer sur cette partie de la question:
Sont des événements d'une abstraction de signal/slots?
Réponse courte: non. La longue réponse soulève une “mieux” question: Comment sont les signaux et les événements liés?
Inactif boucle principale (Qt par exemple) est généralement “coincé” dans un appel select() du système d'exploitation. Cet appel fait de l'application de “sommeil”, alors qu'il passe un tas de douilles ou des fichiers ou que ce soit pour le noyau demander: si quelque chose change sur ces, laisser le select() de retour d'appel. – Et le noyau, comme le maître du monde, ne sait quand cela se produit.
Le résultat de l'appel select() pourrait être: de nouvelles données sur la socket se connecter à X11, un paquet à un port UDP nous écouter sur entrée, etc. – ce genre de choses n'est ni un signal Qt, ni un événement de Qt et Qt boucle principale décide elle-même si elle tourne les frais de données dans l'un, l'autre ou l'ignore.
Qt pourrait appeler une méthode (ou plusieurs) comme événement keypressevent(), a pour effet de transformer en un événement de Qt. Ou Qt émet un signal qui, en effet, cherche toutes les fonctions enregistrées pour ce signal, et les appelle l'un après l'autre.
Une différence de ces deux concepts est visible ici: un logement a pas de vote sur si d'autres emplacements enregistrés pour ce signal sera appelée ou non. – Les événements sont plus comme une chaîne, et le gestionnaire d'événement décide si elle interrompt la chaîne ou pas. Les signaux de ressembler à une star ou d'un arbre à cet égard.
Un événement peut déclencher ou être entièrement transformé en un signal (juste émettent un, et de ne pas l'appeler “super()”). Un signal peut être transformé en un événement (appel d'un gestionnaire d'événement).
Ce que les résumés de quoi dépend le cas: la clicked()-signal résumés des événements de la souris (bouton va vers le bas et de nouveau sans trop se déplaçant autour). Les événements de clavier sont des abstractions des niveaux inférieurs (des choses comme 果 ou é de plusieurs coups de clés sur mon système).
Peut-être le focusInEvent() est un exemple du contraire: il pourrait utiliser (et donc abstrait), l'clicked() du signal, mais je ne sais pas si dans la réalité.
Les événements sont distribués par la boucle d'événements. Chaque programme GUI a besoin d'une boucle d'événements, ce que vous écrivez Windows ou Linux, en utilisant Qt, Win32, ou de toute autre bibliothèque d'interface graphique. Ainsi chaque thread possède sa propre boucle d'événements. Dans Qt "GUI Boucle d'Événement" (qui est la boucle principale de toutes les applications Qt) est caché, mais vous commencez à en appelant:
Messages d'OS et d'autres applications envoyer à votre programme sont expédiés dans les événements.
Signaux et slots de Qt sont des mécanismes. Dans le processus de compilations à l'aide de moc (meta-object compilateur), ils sont changés pour des fonctions de rappel.
Événement doit avoir un récepteur, ce qui devrait l'envoi. Personne d'autre ne doit obtenir cet événement.
Toutes les fentes connecté au signal émis sera exécuté.
Vous ne devriez pas penser à des Signaux d'événements, car comme vous pouvez le lire dans la documentation de Qt:
Lorsque vous envoyez un événement, il faut attendre un certain temps jusqu'à ce que la boucle d'événements, les dépêches de tous les événements qui sont arrivés plus tôt. De ce fait, l'exécution du code après l'envoi de l'événement ou le signal est différent. Code à la suite de l'envoi d'un événement sera exécuté immédiatement. Avec les signaux et les slots mécanismes, il dépend du type de connexion. Normalement, il sera exécuté après toutes les machines à sous. À l'aide de Qt::QueuedConnection, il sera exécuté immédiatement, tout comme les événements. Vérifier tous les types de connexion dans la documentation de Qt.
When you send an event, it must wait for time when event loop dispatch all events that came earlier. Because of this, execution of the cod after sending event or signal is different
Il y a un article qui traite de traitement des événements dans le détail: http://www.packtpub.com/article/events-and-signals
Il des discussions de la différence entre les événements et les signaux ici:
Cela semble être une façon commune de parler d'elle, que l'on a accepté la réponse utilise certains des mêmes phrases.
Remarque, veuillez voir les commentaires ci-dessous sur cette réponse de Kuba Ober, qui me font me demander si elle pourrait être un peu simpliste.
event
. Les signaux et les slots, sont, concrètement, les méthodes, tandis que le mécanisme de connexion est une structure de données qui permet au signal d'invoquer un ou plusieurs emplacements répertoriés comme connecté. J'espère vous voir que de parler de signaux/slots que certains "sous-ensemble" ou "variante" d'événements est un non-sens, et vice versa. Ils sont vraiment des choses différentes que arriver pour être utilisé à des extrémités dans le contexte de certains widgets. C'est tout. Plus vous généraliser, du moins utile, vous devenez à mon humble avis.TL;DR: les Signaux et les slots sont indirectes, les appels de méthode. Les événements sont des structures de données. Donc, ils sont très différents des animaux.
Le seul moment où ils viennent ensemble, c'est quand le logement, les appels sont effectués dans les limites de thread. Le logement arguments d'appel sont emballés dans une structure de données et de m'envoyé comme un événement à la réception de la fil de la file d'attente des événements. Dans le fil, le
QObject::event
méthode déballe les arguments, exécute l'appel, et éventuellement renvoie le résultat si c'était un blocage de la connexion.Si nous sommes prêts à généraliser à l'oubli, on pourrait penser à des événements comme un moyen d'invoquer la cible de l'objet
event
méthode. C'est une méthode indirecte d'appel, après une mode, mais je ne pense pas que c'est une manière utile de penser à ce sujet, même si c'est une véritable déclaration.Événements (dans un sens général de l'utilisateur/réseau d'interaction) sont généralement traités dans Qt avec les signaux/slots, mais les signaux/slots pouvez faire beaucoup d'autres choses.
QEvent et de ses sous-classes sont en fait que peu de données normalisées des packages pour le cadre de communiquer avec votre code. Si vous voulez faire attention à la souris, d'une certaine façon, vous n'avez qu'à regarder la QMouseEvent API, et la bibliothèque, les concepteurs n'ont pas à réinventer la roue à chaque fois que vous devez comprendre ce que la souris n'a dans un coin de l'intervalle Qt de l'API.
Il est vrai que si vous êtes en attente pour les événements (à nouveau dans le cas général), de la sorte, votre logement sera presque certainement accepter un QEvent sous-classe comme un argument.
Avec cela dit, les signaux et les slots peuvent certainement être utilisées sans QEvents, bien que vous trouverez que l'impulsion initiale pour l'activation d'un signal sera souvent une sorte d'interaction de l'utilisateur ou d'autres asynchrone de l'activité. Parfois, cependant, votre code sera juste arriver à un point où de tirer un certain signal sera la bonne chose à faire. Par exemple, de tirer un signal connecté à un la barre de progression au cours d'un long processus n'implique pas une QEvent jusqu'à ce point.
Un autre mineur, la prise en compte pragmatique: l'émission et la réception de signaux, il faut hériter de
QObject
alors qu'un objet de tout l'héritage peut poster ou envoyer un événement (puisque vous invoquezQCoreApplication.sendEvent()
oupostEvent()
) Ce n'est généralement pas un problème mais: utiliser des signaux PyQt étrangement nécessiteQObject
pour être le premier super classe, et vous pourriez ne pas vouloir réorganiser votre ordre d'héritage juste pour être en mesure d'envoyer des signaux.)À mon avis, les événements sont totalement redondante et peut être jeté. Il n'y a aucune raison pourquoi les signaux ne pourraient pas être remplacés par des événements ou des événements par des signaux, sauf que Qt est déjà mis en place comme il est. En attente de signaux sont enveloppés par les événements et les événements qui pourraient parfaitement être enveloppé par des signaux, par exemple:
De remplacer la commodité
mouseMoveEvent()
fonction trouvée dansQWidget
(mais pas dansQQuickItem
plus) et serait en mesure de gérermouseMove
signaux d'une scène, le responsable émettent de l'élément. Le fait que le signal est émis au nom de l'élément par certains à l'extérieur de l'entité n'a pas d'importance et se produit assez souvent dans le monde des composants de Qt, même si c'est soi-disant pas autorisé (composants de Qt souvent de contourner cette règle). Mais Qt est un conglomérat de plusieurs décisions relatives à la conception et à peu près immuables de peur de briser l'ancien code (ce qui arrive assez souvent quand même).QObject
hiérarchie parent-enfant, lorsque cela est nécessaire. Signal/slot connexions sont juste une promesse pour appeler une fonction, directement ou indirectement, lorsqu'une certaine condition est remplie. Il n'y a pas un associé de la manipulation de la hiérarchie avec les signaux et les slots.accepted
paramètre de référence à un signal et les fentes de le manipuler ou vous pourriez avoir une structure comme un paramètre de référence avec unaccepted
champ. Mais Qt fait le choix de conception il fait et ils sont maintenant fixés dans la pierre.J'ai trouvé cette question lors de la lecture de L'événement de transformation' par Leow Wee Kheng. Il dit aussi: