Diskussion:Signal-Slot-Konzept

aus Wikipedia, der freien Enzyklopädie

Code Beispiel, nicht nachvollziebar

Tut mir leid, kenne Funktionszeiger, Callbacks, Delegates, das Observer Pattern, etc... also was Ereignisbehandlung angeht verstehe ich durchaus das Konzept, und die die Syntax mehrerer Sprachen, aber was dieses Beispiel betrifft kann ich nur raten. Wenn du keine Lust hast den Code zu dokumentieren und die zugrundelegende Syntax zu erörtern solltest du wenigstens einen Link auf eine entsprechende Referenz einfügen. Vielleicht bin ich ja auch schlicht weg zu dumm (kommt gelegentlich schon mal vor :) 3 Fragen - mit den Augen eines staunenden Kindes:

1. Wo ist die Implementierung zu "void wertGeaendert(int);" wenn du den Code für setzeWert() und wert() angibst, warum nicht auch für wertGeaendert() ? Und das obwohl hier das ominöse emit zur Anwendung kommt. Ist es überhaupt eine klassische Methoden-Deklaration ? (Natürlich nicht aber ich muss ja raten :) Wenn ja, was deklarierst du hier sonst ?

Ich deklariere ein Signal. Ein Signal braucht nicht von implementiert werden. Das mach der Meta-Objekt-Compiler! --Thornard, Diskussion, 01:29, 11. Okt. 2006 (CEST)

2. Wieso verändert der Aufruf von setzeWert() plötzlich auch die Instanz b ? Wie kann instanz b plötzlich auf Instanz a zugreifen, denn die Daten der beiden sind im Speicher getrennt, darum gehts ja u.a. bei der OO - Datenkapselung. Woher weiß a überhaupt von b ? (Hast du nur das static vergessen - natürlich Blödsinn, aber in meiner Verzweiflung komm ich schon auf die seltsamsten Ideen, denn - ich muss immer noch raten:)

Lese dir doch den Artikel mal durch. Das steht doch in der Übersicht. --Thornard, Diskussion, 01:29, 11. Okt. 2006 (CEST)

3. Was passiert hier, kommt eine Art von Makroprozessor, also Textersetzung zur Anwendung (glaub ich nicht wirklich, aber wie gesagt ich muss ja raten :), was ist in dem ominösen Header <QObject> enthalten den du includierst, und was hat das noch viel ominösere Q_OBJECT mitten in der Klassen Definition zu bedeuten...

Ja es kommt eine Makroprozessor zum Einsatz. --Thornard, Diskussion, 01:29, 11. Okt. 2006 (CEST)

Natürlich kann ich mir letzendlich herleiten was passiert. Dem Platzhalter wertGeaendert von Instanz-a wird mittels ::connect() die setzeWert-Methode von Instanz-b zugewiesen und dann bei der nächsten Abareitung von setzeWert(), in Instanz-a, aufgerufen. Deshalb reicht a (falls der neue Wert nicht gleich dem alten ist) den übergebenen Wert an b weiter. Aber wo ist der Unterschied zum Vorgehen mittels Funktionszeigern. Ich wüsste nicht wie das ohne Zeiger funktionieren sollte. Wie gesagt ich kanns mir grad noch herleiten, viele andere die nur mal neugierig sind sicherlich nicht. Ausserdem mag ich es nicht raten zu müssen :) Gib uns eine Chance.

Der Unterschied liegt daran, dass Funktionszeiger keine Typsicherheit und keine wirklichen unabhängigen Obejekte ermöglichen, da das Zielobjekt die Typen des Quellobjektes kennen muss. --Thornard, Diskussion, 01:29, 11. Okt. 2006 (CEST)

Logik ist immer nachvollziehbar, du gehst von irgrendwelchen Prämissen aus und erwähnst nocht nicht mal welche. Bitte füge doch einen Link auf eine entsprechende Referenz ein, oder besser noch erkläre das zugrundeliegende Prinzip in wenigen Sätzen.

Im Prinzip hast du recht. Das Verfahren ist echt abgefahren. Doch kann man es in der Qt-Dokumentation gut nachlesen. Vielleicht findet sich jemand, der das besser in Worte fassen kann. Ich werde versuchen es noch etwas auszubauen. --Thornard, Diskussion, 01:29, 11. Okt. 2006 (CEST)

Was beispielsweise mich persönlich wirklich interessieren würde: Können nur Zeiger auf Methoden von Zahl Instanzen mit einem int Param. übergeben werden, oder jede Funktion mit entsprechender Signatur. Bleibt die Koppelung bestehen oder ist sie nur einmalig, bzw. wie entfernt man die Referenzen wieder. Können mehrere Funktionszeiger übergeben werden, ist also eine Liste von Zeigern möglich ? --mws 20:47, 5. Jul 2006 (CEST)MichaelSchreyer

Es ist leider alles etwas Komplizierter. Wikipedia ist kein Forum um dir Qt-Programmierung beizubringen. Doch hast du natürlich recht, dass die Artikel in der Wikipedia verständlich sein sollten. Vielleicht finde ich oder irgendjemand anderes noch Zeit das etwas weiter auszubauen. Unter Qt gibt es weiterführende Links. Viel Spaß. --Thornard, Diskussion, 01:29, 11. Okt. 2006 (CEST)

Unterschied zu Callbacks?

du betonst die Unterschiedlichkeit zwischen dem Signal-Slot-Konzept und Callbacks, aber worin besteht diese überhaupt? Was ist denn so ein Slot anderes als eine Callback-Funktion? Nach meinem Verständnis ist ein Callback eine Funktion, die man einem Funktionspointer zuweist und dann über diesen aufruft - in einem Programmteil wo die Funktion selbst nicht bekannt ist sondern eben nur der Funktionspointer. Demnach aber wäre ein Signal einfach der Funktionspointer, und der Slot wäre die Callback-Funktion. Und die Funktion connect() würde den Callback installieren. -- 06:35, 25. Nov 2006 (CEST)

Versuch einer Erklärung: Mit Callbacks kann man natürlich alles machen. Probleme damit ergeben sich aber bei größeren Projekten hinsichtlich Übersichtlichkeit, Wartbarkeit und damit indirekt der Effizienz. Sind die Schnittstellen beim Beginn der Entwicklung bekannt und ist man sicher, daß sie sich nicht ändern, gibt es immer eine optimalere Programmversion mit Callbacks. Ein Beispiel, wo man die Vorteile des Konzeptes erst sehen würde, ist natürlich zu groß für hier.

Wie im Artikel richtig erwähnt, ist das Signal - Slot - Konzept eine Ausprägung des Observer-Patterns. Das Gleiche, was zum Verwenden des Observerpattern motiviert, gilt deshalb auch hier. An der Erklärung im Wiki zum Observerpattern stört mich, daß sie zu sehr am Code hängt. Es fehlt eine Motivation der Idee für Nicht-Programmierer. Ein Versuch:

Das Observerpattern bzw. das Signal-Slot-Konzept stammt aus dem Alltagsleben: Die Tageszeitung, das Anzeigenforum, die Heirats/Wohnungs/..vermittlung. Anstatt jeden Mitmenschen persönlich zu informieren, nach was man sucht, gibt man ein Inserat auf. Genauso wenn man etwas Bestimmtes zu bieten hat. Bieter und Suchender finden zueinander, ohne vorher irgendetwas voneinander zu wissen, wenn sie die Tageszeitung benutzen können. Die Signale wären dann die verschiedenen Anzeigenrubriken, "Suche 3-Zi-Whg", "Sie sucht Ihn".. Ein ZeitungsInserat entspricht einem Connect. Ein Slot entspicht dem Lesen einer Anzeigenrubrik. Z.B. liest ein Wohnungsvermieter nach Mietgesuchen , nicht nach Heiratsinseraten.

Ist das System von Signalen und Slots nicht etwas anders? Bieter (=Sender von Signalen) und Suchender (=Empfänger von Signalen) finden nicht irgendwie zueinander, sondern werden fest miteinander verbunden (durch connect) und nur die angemeldeten Empfänger erhalten die Signale. Hier ein zweiter Erklärungsversuch:
Jemand sammelt Informationen (z.B. über den Wohnungsmarkt), die für andere interessant sein könnten. Diese veröffentlicht er in einem Anzeigenblatt (=Signal). Andere interessieren sich für Informationen über den Wohnungsmarkt und abonnieren daher das Anzeigenblatt (=connect). Diese Abonnenten erhalten nun regelmäßig Informationen über den Wohnungsmarkt und werden je nach Inhalt der Anzeige tätig (=Slot).

Das Konzept von Anzeigenblättern ist seit 100 Jahren genau gleich, obwohl sich die Art der Anzeigen täglich ändert. Ein sehr generisches und deshalb geeignetes Konzept.


Neuer Erklärungsversuch

Wenn du ein klassisches Callback machst, gibst du einen Pointer auf eine Funktion, verlierst aber die "Signatur", also die Information, ob und welche Art von Argumenten deine Callback-Funktion hat. Wenn du jetzt eine Funktion als Callback registriert, die nicht "passt", stürzt dein Programm ab. Bei Signals und Slots hast du die Information über die Argumente im Signalnamen mit drinn: SIGNAL(valueChanged(int)). Das int in Klamern sagt aus, dass das Signal nur mit einem Slot verbunden werden kann, der ein int erwartet (oder weniger). Wenns nicht passt, klappt das Connect nicht und es kommt eine Warnung auf der Konsole. Das ist der Vorteil: Kein kryptischer Absturz, sondern eine Überprüfung, ob es passt, bevor es knallt. --130.83.220.159 23:18, 1. Jan. 2009 (CET)


2. und 3. Code-Beispiele: Highliter

Ich währe dafür, dass man bei den Beispielen den von Wikipedia eingesetzten Highliter hier zuverwenden. Als Style würde ich "cpp-qt" vorschlagen. Bitte auf rückmeldung von euch. -- Sebi-Book 16:31, 5. Nov. 2009 (CET)

Ja klar, warum nicht?--Ma-Lik ? +/- 18:03, 5. Nov. 2009 (CET)
Habs nun mal geändert. -- Sebi-Book 01:09, 7. Nov. 2009 (CET)
"Warum nicht?": Weil man in der alten Version (rote Hervorhebung der Signale, Slots usw.) sofort die Änderungen gegenüber einem anderen Programm erkennen kann. Ich finde das sehr viel wichtiger und für den Artikel verständlicher als die bunte Hervorhebung der C++-Syntax, auf die es in dem Beispiel gar nicht ankommt (da hilft es auch nicht, daß es einen speziellen cpp-qt-Style gibt). Im jetzigen Artikel muß man die wichtigen Stellen ja erst suchen. Ich bin für eine Wiederherstellung der vorherigen Version. 93.195.180.213 16:01, 16. Feb. 2010 (CET)

Unterschied zu DataBusPattern?

Ist das Konzept das selbe wie das DataBusPattern? s. http://c2.com/cgi/wiki?DataBusPattern?

(Geht es hier um ein Abstraktes Konzept? Hat nur QT das? Lässt sich das ganze auch als abstrakter Code ohne QT/Präprozessor usw. beschreiben?)

Der ganze erste beschreibende Absatz geht etwas daneben soweit ich das beurteilen kann (wollte ja eben rausfinden was Signal/Slot genau ist). Zum einen unterscheidet sich Signal/Slot ja gerade fundamental vom Observer darin, dass die Teilnehmer sich *nicht kennen* müssen. Zum anderen sind "Callbacks" ja eben schon *Typsicher* (ein Callback ist in C ein Funktionszeiger. Als solcher hat er einen Type der seine Argumente beinhaltet.) (nicht signierter Beitrag von 188.174.85.233 (Diskussion) 16:56, 12. Dez. 2014 (CET))