Gibt es eine praktische Alternative zum Signal + Slots-Modell für die GUI-Programmierung?

9

Die meisten GUI-Toolkits verwenden heutzutage das Modell Signals + Slots. Es waren Qt und GTK +, wenn ich mich nicht irre, die Pionierarbeit geleistet haben.

Sie wissen, dass die Widgets oder grafischen Objekte (manchmal sogar solche, die nicht angezeigt werden) Signale an den Main-Loop-Handler senden . Der Main-Loop-Handler ruft dann die Ereignisse , Rückrufe oder Slots auf, die für dieses Widget / grafische Objekt zugewiesen sind. Im virtualGegensatz zu früheren Designs, bei denen der Entwickler die gesamte Hauptschleife und den Handler für jede einzelne Nachricht selbst schreiben musste, gibt es normalerweise bereits vom Toolkit bereitgestellte (und in den meisten Fällen ) Event-Handler, die alle vordefinierten Signale verarbeiten (denken Sie an WINAPI), der Entwickler muss sich nur um die Signale kümmern, auf denen er neue Funktionen implementieren muss.

Soweit ich weiß, wird dieses Design jetzt in den meisten modernen Toolkits verwendet. Es gibt Qt, GTK +, FLTK usw. Es gibt Java Swing. C # verfügt sogar über eine Sprachfunktion (Ereignisse und Delegaten), und Windows Forms wurde für dieses Design entwickelt. Tatsächlich ist dieses Design für die GUI-Programmierung im letzten Jahrzehnt zu einer Art ungeschriebenem Standard geworden. Da es die Produktivität erhöht und eine größere Abstraktion bietet.

Meine Frage ist jedoch:

Gibt es ein alternatives Design, das für die moderne GUI-Programmierung parallel oder praktisch ist?

dh Ist das Signal + Slots-Design das einzige praktische in der Stadt? Ist es möglich, GUI-Programmierung mit einem anderen Design durchzuführen? Sind moderne (vorzugsweise erfolgreiche und beliebte) GUI-Toolkits auf einem alternativen Design aufgebaut?

ApprenticeHacker
quelle
Das Paradigma der Nachrichtenwarteschlange, das Sie in der Windows-API finden, ähnelt nicht Ereignissen und Delegaten. Die Delegierten werden synchron und unmittelbar, wie genannt std::function, nicht ein asynchrones Signal. Darüber hinaus ist die WinAPI nicht zur Verfügung stellen , DefWindowProcwelche Windows - Nachrichten als Default - Implementierung verarbeitet. Ich gehe also davon aus, dass Ihre Frage auf einer fehlerhaften Logik basiert.
DeadMG
2
QT und GTK + sind keineswegs die ersten GUI-Frameworks, die einen ereignisgesteuerten Ansatz verwenden. Das Konzept reicht zurück bis Smalltalk-80 ( en.wikipedia.org/wiki/Smalltalk ).
Doc Brown
Interessante Frage, ich bin gespannt, ob sich dieses Modell mit Multi-Touch-Interfaces stark verändert.
Ben DeMott
Ich wäre großzügig und würde annehmen, dass er SendMessage kennt, das synonym ist, nicht nur PostMessage. Er irrt sich jedoch immer noch darin, dass Sie nie für jede Nachricht die gesamte Nachrichtenverarbeitungsschleife schreiben mussten.
Gbjbaanb
JavaFx bietet einen ähnlichen Mechanismus über seine Bindungs-APIs.
Eng.Fouad

Antworten:

5

Das ist ein Lieblingsthema von mir, und für ungefähr ein Jahrzehnt ('70er bis '86) dachte ich, dass eine GUI, die aus Objekten besteht, die auf Ereignisse reagieren, genau der richtige Weg ist, dies zu tun.

Dann bin ich auf einen anderen Weg gestoßen, um es hier und mit einem Sourceforge-Projekt hier zu tun .

Kurz gesagt, das Problem mit Objekten besteht darin, dass sie bestehen bleiben. Wenn Sie Code schreiben, um sie zu erstellen, müssen Sie auch Code schreiben, um sie schrittweise zu ändern, wenn Änderungen erforderlich sind, und irgendwie Nachrichten von und zu ihnen zu erhalten. Wäre es nicht schön, wenn Sie nur malen könnten, was Sie wollten, und es dann neu streichen könnten, wenn Sie etwas anderes wollen und sich nicht um die Beständigkeit früherer Objekte sorgen müssten? Wäre es nicht auch schön, wenn Sie nie Code für die Nachrichtenverarbeitung schreiben müssten, weil alles unter der Haube erledigt wird?

Das macht dieses Paket. Für einfache Dialoge wird eine Größenordnung im Code gespeichert. Für komplexe, sich dynamisch ändernde Dialoge werden diese ermöglicht.

PS Ich habe dies nur für Desktop- und Remote-Terminal-Benutzeroberflächen durchgeführt, nicht für Webbrowser-Benutzeroberflächen. Ich bin mir sicher, dass es möglich ist, aber ich hatte noch keine Gelegenheit, es zu versuchen.

Mike Dunlavey
quelle
+1, Aber wie ist es möglich, zusätzliche Funktionen wie benutzerdefinierte Eingaben zu erzielen?
ApprenticeHacker
@IntermediateHacker: Ich bin nicht sicher, was Sie unter benutzerdefinierten Eingaben verstehen. Meinen Sie eine Formulardesigner-App?
Mike Dunlavey
2

Nun, es gibt zwei verschiedene Möglichkeiten, dies zu tun:

  1. Lassen Sie jedes Widget einen detaillierten Abonnementmechanismus (Signal / Slot, Observer / Observable, Event / Delegate) bereitstellen und den Clientcode abonnieren und entsprechende Maßnahmen ergreifen.
  2. Erstellt ein Widget gegen eine Abstraktion der präsentierten Daten und lässt Client-Code diese Abstraktion implementieren.

Hier ist ein Beispiel für den zweiten Ansatz:

interface Action {
     void execute();
     Bool isEnabled();
     Null<String> description();//used for tooltip
}
interface LabledAction extends Action {
     String getName();
}

Und jetzt können Sie einen LabelButtongegen einen LabledActionerstellen und der Client-Code kann ihn einfach implementieren oder eine generische Standardimplementierung verwenden, sofern verfügbar und geeignet.

In gewisser Weise ist der zweite Ansatz weniger flexibel, aber starrer. Sie verbinden die Ansicht nicht einfach auf relativ atomare Weise mit dem Modell. Sie entwerfen eine geeignete GUI basierend auf Ihren Anforderungen und implementieren dann die Adapter zwischen dieser GUI und Ihrer Domänen- / Anwendungslogik.

back2dos
quelle
Modell / Ansicht / Controller ist gut, aber es ist nur eine Erweiterung des Beobachtermusters, da der Controller-Teil nur ein Beobachter des Widgets ist und im Modellteil das Widget Beobachter des Modells ist, also ist es umgekehrt der gleiche Mechanismus .
Jan Hudec
1

Einige Steuerungssysteme verwenden einen Datenbankansatz. Jedes GUI-Steuerelement ist mit einem in der Datenbank abgelegten Steuerelement verknüpft, sodass das GUI immer den Datenbankstatus widerspiegelt. DB-Hooks werden verwendet, um Funktionen auszulösen, wenn sich ein Wert ändert.

Martin Beckett
quelle
4
Ist das nicht immer noch ein Signal-Slot mit einer zusätzlichen DB-Schicht?
Ratschenfreak
Letztendlich sind alles Interrupts oder Rückrufe - es sind die einzigen asynchronen Operationen auf niedriger Ebene
Martin Beckett