2008-11-23 12 views
13

Kann jemand in einfachen Worten das Muster "Signale und Schlitze" erklären?Was sind Signale und Slots?

+1

meinst du Qt Signale und Steckplätze? –

+0

Das Muster im Allgemeinen. Wikipedia zeigt an, dass Boost es auch tut. – JeffV

Antwort

18

Signale und Slots sind eine Möglichkeit, einen Sender (das Signal) und null oder mehr Empfänger (die Slots) zu entkoppeln. Nehmen wir an, Sie haben ein System mit Ereignissen, die Sie für andere Teile des Systems, die an diesen Ereignissen interessiert sind, bereitstellen wollen. Anstatt den Code, der das Ereignis generiert, fest mit dem Code zu verbinden, der über diese Ereignisse informiert werden möchte, würden Sie ein Signal- und Zeitschlitzmuster verwenden.

Wenn der Sender ein Ereignis signalisiert (normalerweise durch Aufruf der mit diesem Ereignis/Signal verbundenen Funktion), werden alle Empfänger für dieses Ereignis automatisch aufgerufen. Auf diese Weise können Sie während der Laufzeit des Programms Empfänger anschließen und trennen.

Da diese Frage C++ getaggt wurde, ist hier ein Link zu der -Bibliothek, die eine viel gründlichere Erklärung hat.

4

Ich nehme an, Sie sprechen über QT-Signale und Slots.
Es ist sehr einfach.

Eine Instanz einer Klasse kann ein Signal auslösen und eine andere Instanz einer anderen Klasse kann dieses Signal in einem Slot fangen. Es ist wie bei einem Funktionsaufruf, dass der Typ, der die Funktion anruft, nicht wissen muss, wer den Anruf erhalten möchte.

Der beste Weg zur Veranschaulichung ist mit einem Beispiel.
Die Klasse QPushButton hat ein Signal QPushButton :: clicked(). Dieses Signal wird ausgelöst, wenn auf die Schaltfläche geklickt wird. Der Druckknopf muss nicht wissen, wer interessiert ist zu wissen, dass ein Klick aufgetreten ist. es feuert nur das Signal und wer daran interessiert ist, kann sich mit ihm verbinden.
Der QDialog, in dem die Schaltfläche platziert ist, ist eigentlich interessiert zu wissen, wann die Schaltfläche geklickt wurde. Es hat den Slot MyDialog :: buttonClicked(). Auf MyDialog c'tor müssen Sie() das buttons click() Signal mit dem buttonClicked() Slot des Dialogs verbinden, damit der Slot beim Auslösen des Signals aufgerufen wird.

Ein Bündel von fortgeschritteneren stuff:

  • Argumente kann ein Signal Argumente haben, und diese Argumente zu dem Schlitz optional kann auch übergeben werden.
  • Cross-Thread-Anrufe - Wenn Sie eine Signal-Slot-Verbindung herstellen, die Cross-Threads sein müssen, puffert QT die Signale automatisch und stellt sie in den richtigen Thread. Dies geschieht beispielsweise automatisch, wenn ein GUI-Thread mit einem arbeitenden Thread kommunizieren muss.

Here's more information in QT's documentation.

12

denke ich, ein Signale und Slots am besten beschreiben können, wenn Sie für die Observer Pattern or Publish/Subscriber Pattern bei ihnen als eine mögliche Implementierung Fahrzeug suchen. Es gibt eine signal, zum Beispiel buttonPressed(IdType) auf der Publisher-Seite. Wenn die Taste gedrückt wird, werden alle mit diesem Signal verbundenen Steckplätze aufgerufen. Slots sind auf der Abonnentenseite. Ein Slot könnte beispielsweise sendMail(IdType) sein.

Zusammen mit dem Ereignis "Taste gedrückt" würde der Slot wissen, welche Taste gedrückt wurde, da die ID übergeben worden wäre. IdType stellt den Typ der Daten dar, die über die Verbindung zwischen dem Verleger und dem Abonnenten gesendet werden. Eine für den Teilnehmer mögliche Operation wäre connect(signal, slot), die buttonPressed(IdType) mit sendMail(IdType) verbinden könnte, so dass, wenn die Taste gedrückt wird, dieser bestimmte Slot aufgerufen wird.

Die gute daran ist, dass die Teilnehmer (der Seitenschlitz) braucht sich nicht um Details des Signals zu sorgen. Es muss nur eine Verbindung herstellen. So, hier haben wir eine Menge von lose Kupplung. Sie können die Implementierung der Schaltflächen ändern, aber die Schnittstelle für die Slots wäre immer noch dieselbe.

Blick auf Qt Signals/Slots oder Boost Signals für weitere Informationen.

6

Stellen Sie sich eine GUI in der Anwendung ist. Die meiste Zeit ist der Kontrollfluss nicht sehr linear, d. H. Anstatt eine klare Abfolge von Aktionen zu haben, würden Sie einen Benutzer haben, der mit der GUI interagiert (wie Knöpfe, Menüs usw.).

Dies ist im Wesentlichen ein ereignisgesteuertes Modell, das ganz gut mit den Signalen und Slots Mustern realisiert werden kann. Signale sind Ereignisse, die von Objekten generiert werden (Think GUI-Komponenten) und Slots sind die Empfänger dieser Ereignisse. Hier

ist ein Beispiel: Stellen Sie eine Checkbox haben, als ein Objekt in Ihrer Programmiersprache dargestellt. Diesem Kontrollkästchen können mehrere Dinge passieren: Es kann umgeschaltet werden, was wiederum bedeutet, dass es entweder gesetzt oder nicht gesetzt ist. Das sind die Signale, die es aussenden kann. Wir nennen sie checkboxToggled, checkboxSet und checkboxUnset. Wie Sie sehen, gibt die Checkbox in diesem Beispiel immer das CheckboxToggled-Signal aus, wenn umgeschaltet wird, aber auch genau eines der beiden anderen Signale, abhängig davon, wie sich der Status ändert.

Stellen Sie sich nun einige andere Objekte vor, nämlich ein Label, das für dieses Beispiel immer als Objekt existiert, aber "erscheinen" und "verschwinden" kann und ein Systempiep (auch dargestellt durch ein Objekt) einfach piepsen. Das sind die Slots, die diese Objekte haben. Wir werden sie "messageAppear", "messageDisappear" und "beep" nennen.

Angenommen, der System-Signalton soll jedes Mal piepen, wenn das Kontrollkästchen aktiviert ist, und die Bezeichnung erscheint oder verschwindet, je nachdem, ob der Benutzer das Kontrollkästchen aktiviert oder deaktiviert hat.

Sie würden die folgenden Signale an die folgenden Steckplätze so verbinden (Signale auf der linken Seite, Slots auf der rechten Seite):

checkboxToggled -> beep 
checkboxSet -> messageAppear 
checkboxUnset -> messageDisappear 

Das ist im Grunde ist es.

Signale und Slots können auch Argumente haben. Wenn Sie beispielsweise einen Schieberegler verwenden, der einen numerischen Wert festlegt, möchten Sie den geänderten Wert zusammen mit dem ausgegebenen Signal senden, sobald der Benutzer den Schieberegler bewegt: sliderChanged (int).

Natürlich tun wirklich etwas Nützliches Sie würde einige eigene Klassen schreiben, die einige eigene Signale und Slots enthalten würde. Dies geschieht sehr einfach und mit diesen eigenen Signalen und Slots, haben Sie eine schöne Möglichkeit, mit der GUI oder anderen Teilen Ihres Codes in einer ereignisgesteuerten Weise zu interagieren.

Beachten Sie, dass Signale und Schlitze oft in dem Sinne symmetrisch sind, dass es oft ein Signal entsprechend einem Schlitz sein kann. Beispielsweise kann ein Kontrollkästchen beim Umschalten ein Signal ausgeben, es kann jedoch auch einen Steckplatz enthalten, der das Kontrollkästchen selbst aktiviert. Es wäre einfach zu implementieren, um Kontrollkästchen zu trennen, die immer entgegengesetzt zueinander gesetzt sind.

1

Das beste Beispiel und Erklärung, die ich für Signale und Slots gefunden haben, ist this code project article.

+2

Beachten Sie, dass [Nur-Link-Antworten] (http://meta.stackoverflow.com/tags/link-only-answers/info) nicht empfohlen werden. SO-Antworten sollten der Endpunkt einer Suche nach einer Lösung sein (vs. ein weiterer Zwischenstopp von Referenzen, die im Laufe der Zeit abgestanden werden). Bitte beachten Sie, dass Sie hier eine eigenständige Zusammenfassung hinzufügen und den Link als Referenz beibehalten. – kleopatra

+0

Ich denke, es ist in Ordnung, Links zu haben. – VivekDev

0

Es ist ein weit verbreitetes Missverständnis, dass Klassen sind Substantive wie Person, Hund, Fahrrad und so weiter. Dann macht es Sinn zu denken, dass eine Person (Instanz) einen Hund und ein Fahrrad hat.

Beginnen wir damit, was Objekte sind (sollen). Objekte sind Daten und Prozeduren. Was sind Programme? Daten und Verfahren. Objekte sollen (relativ) "kleine" unabhängige Unterprogramme sein. Weil oo Programmierung sehr vage gelehrt und missbraucht wird (Zitat benötigt), denken die Leute, dass alles eine Klasse oder ein Objekt sein muss. Dies ist nicht so, Objekte sind "kleine" unabhängige Programme mit einer "kleinen" API (öffentliche Subroutinen). Einige Programmierer brechen ihr Projekt nicht einmal in Unterprogramme auf und verwenden einfach Objekte, in denen Daten und Prozeduren besser geeignet sind.

Wenn wir nun zustimmen, dass Objekte Programme sind, können wir zustimmen, dass Programme in den meisten Fällen keine Kopien anderer Programme ähnlicher Größe und Komplexität benötigen (dh ein Objekt weist keinen Zeiger auf einen anderen) Objekt), benötigt es möglicherweise kleinere Programme zur Verwaltung von Daten (wie Datenstrukturen), aber imho braucht kein anderes Objekt.

Warum? Weil das Koppeln von Objekten sie abhängig macht. Warum ist das so schlimm? Denn wenn Objekte unabhängig sind, können Sie sie testen und auch anderen Programmierern und Clients versprechen, dass das Objekt (ein kleines unabhängiges Programm) in der Lage ist, bestimmte Aufgaben mit hoher Sicherheit auszuführen. Sie können auch sicher sein, dass die Ausführung fortgesetzt wird, solange keine Änderungen an diesem Objekt vorgenommen wurden.

Was sind Slots und Signale? Wenn Sie verstehen, dass Objekte wie Programme sind und sie im Idealfall keine Kopien oder Zeiger auf andere Objekte halten sollen, brauchen Sie eine Möglichkeit, damit sie kommunizieren können. Beispielsweise können Prozesse, die auf Ihrem Computer ausgeführt werden, Sockets, IP-Adressen und Ports für die Kommunikation verwenden. Objekte können etwas sehr ähnliches wie RPC genannte Signale und Slots verwenden. Dies ist eine Datenstruktur, die als Vermittler zwischen zwei größeren Objekten dient, die Subroutinen des Objekts speichern (slots) und anderen Objekten erlauben, diese Subrutinen (signal) mit geeigneten Parametern aufzurufen, ohne etwas über diese anderen Objekte außer den Parametern zu wissen benötigen.

Also die zugrunde liegende Struktur sind Mengen (möglicherweise Arrays) von (möglicherweise) stark typisierten Prozedurzeigern, die andere Objekte mit geeigneten Parametern ohne einen Zeiger auf diese Objekte aufrufen können. Die Aufrufer benötigen nur Zugriff auf das Signalobjekt (das keine Implementierungsdetails enthält), das die erwarteten Parameter definiert.

Dies ist auch flexibel, da es einige spezielle Anwendungsfälle wie Slots, die nur auf das Signal reagieren, mehrere Slots für ein Signal und andere ähnliche Anwendungsfälle wie Entprellen erlaubt.