Universelle GUI ~ = Ende des Elends

FĂŒr mich ist die ideale BenutzeroberflĂ€che eine App, die keine Programmierung, kein Design und keine Wartung erfordert und mit jeder Sprache und auf jeder Plattform ohne Änderungen gleichermaßen arbeiten kann. Ist es in unserem Leben möglich, werden wir versuchen, es herauszufinden.

Es ist einfach, individuell etwas von Vue / React, JavaFX, Python PyQt usw. zu lernen, aber Daten abzurufen und auf einfache und elegante Weise mit dem Software-Zoo zu interagieren, ohne an Benutzer-Betriebssysteme / Browser / Plattformen zu denken, ist eine ungelöste Aufgabe fĂŒr solche Tools. Ich möchte nicht in das neue Framework (auch nicht in das alte, vergessene) einsteigen, die Programmiersprache Ă€ndern, den Rechen harken und meinen Kopf mit MĂŒll verstopfen. Ich möchte genau meine Aufgabe programmieren, ohne vom Kampf mit allen möglichen GUI-Frameworks abgelenkt zu werden. Und ich habe eine Lösung fĂŒr mich gefunden.

Als Austauschprotokoll werden wir Json als Top-Format in Bezug auf PopularitĂ€t / VerstĂ€ndlichkeit / Lesbarkeit / UnterstĂŒtzung in allen Programmiersprachen bis zu dem einen oder anderen Grad verwenden.

Der Server sendet Json-Daten, nach denen unsere App-GUI ein Bild entwerfen soll, das den Spezifikationen einer schönen GUI entspricht. Google mit seinem Materialdesign ist heute der Standard.

Zu den Anforderungen fĂŒr eine moderne BenutzeroberflĂ€che gehört das Vorhandensein von Standardelementen wie SchaltflĂ€chen, Eingabefeldern, Tabellen usw. Lassen Sie uns abschĂ€tzen, wie die Mindestkonventionen verwendet werden, um der BenutzeroberflĂ€che mitzuteilen, dass bestimmte Elemente auf dem Bildschirm benötigt werden. Hier sind die wichtigsten:

  • Zustandsloser Knopf {'Name': 'Push me'}. Wenn das Element nur einen Namen enthĂ€lt, handelt es sich um eine SchaltflĂ€che.
  • Das Eingabefeld lautet {'name': 'Edit me', 'value': ''}, da der Typwert eine Zeichenfolge ist.
  • Die Umschalttaste {'name': 'Mein Status', 'Wert': false}, da der Typ false boolesch ist.
  • WĂ€hlen Sie aus der Liste {'Name': 'Etwas wechseln', Wert: 'Wahl1', Optionen = ['Wahl1', 'Wahl2', 'Wahl3']}
  • {‘name’:’Image, ‘url'’: ’..’, ‘width’: .., ‘height’:
 }
  • {‘name’:’My table’, 'headers'=[‘Name’, ‘Synonym’], rows = [
    [‘young’, ‘youthful’],
    [‘small’, ‘ meager’],
    ...]
    }

Zur Anpassung können Sie den Elementtyp auf {type: 'ButtonSwitcher'} setzen, wenn der von JSON automatisch ausgewÀhlte Typ nicht zu Ihnen passt. Dies ist möglich, wenn derselbe JSON auf mehrere Arten angezeigt werden kann. Beispielsweise kann "Aus einer Liste auswÀhlen" als Eingabefeld mit einer Dropdown-Liste dargestellt werden, oder es kann sich auch um einen horizontalen Satz von SchaltflÀchen handeln, von denen eine aktiv ist und dem aktuellen Wert entspricht.

Bei einer kleinen Anzahl von Optionen ist es sinnvoll, die SchaltflĂ€chenoption automatisch zu verwenden, bei einer großen Anzahl (mehr als 3) - einem Eingabeauswahlfeld. Unsere GUI selbst wĂ€hlt den besten Weg zum Rendern, aber wenn Sie es wirklich brauchen - geben Sie Folgendes ein: ... um zu helfen. Normalerweise wird der Typ nicht benötigt und der Autodesigner muss alleine zurechtkommen.

VervollstÀndigen wir das Bild im Detail:

  • Wenn der Name nicht auf dem Bildschirm angezeigt werden soll, muss er mit _ beginnen.
  • - , ‘icon’: ‘ Material Design ’; push - {‘name’: ‘_Check’, ‘icon’: ‘check’}
  • , Viewers, , ‘colors’, ‘params’,
 // . — , .

FĂŒr die logische Gruppierung von Elementen fĂŒhren wir das Konzept eines Blocks ein, der logisch verwandte Elemente in einem visuellen Block gruppiert.

{'name': 'Block 1', 'elems': [{'name': '_Check', 'icon': 'check'}, ...]}
Innerhalb des Blocks mĂŒssen alle Elemente eindeutige Namen haben, da sie id sind .

Normalerweise werden Blöcke horizontal erstellt, wenn sie nicht auf alle Bildschirme passen (sie haben beispielsweise die App-BenutzeroberflĂ€che auf einem Mobiltelefon gestartet). Der automatische Designer blendet sie aus, fĂŒgt der Symbolleiste jedoch Symbole hinzu, mit denen sie mit einem Fingertipp geöffnet werden können. Dies gibt Ihnen die Möglichkeit, auch auf kleinen Bildschirmen mit einer komplexen BenutzeroberflĂ€che zu arbeiten.

Die oberste Beschreibungsebene ist Bildschirm. Es sieht aus wie {'Name': 'Screan', Blöcke: [..], MenĂŒ: [{'Name': 'Bildschirm', 'Symbol': ..,}, ..], 'Symbolleiste': [JSON-Set - Elemente (SchaltflĂ€chen, Felder, was auch immer)]}

FĂŒgen Sie Implementierungsdetails fĂŒr die bedingte uniGUI hinzu, die unser JSON-Protokoll unterstĂŒtzt. Es handelt sich um einen separaten Prozess, der mit dem Websocket-Datenserver kommuniziert und dessen Daten anzeigt und anschließend alle fĂŒr den Server wichtigen Aktualisierungen dieser Daten meldet.

Bei der Verbindung mit dem Server erwartet uniGUI den Empfang des Bildschirms. Nachdem er es erhalten hat, entwirft und zeichnet er die empfangenen Informationen auf optimale Weise fĂŒr den aktuellen Bildschirm des Benutzers und wartet dann auf eine Reaktion des Benutzers und des Servers. Aus dem erstellten Datenabbild empfĂ€ngt der Server einen Stream von JSON-Nachrichten, die vollstĂ€ndig beschreiben, was der Benutzer getan hat. Sie haben die Form ['Block', 'Elem', 'Aktionstyp', 'Wert'], wobei 'Block' und 'Elem' die Namen des Blocks und Elements sind, Wert der Wert des Ereignisses.

Der Server kann die Änderung entweder akzeptieren oder zurĂŒcksetzen, indem er ein Infofenster ĂŒber die Diskrepanz sendet. Es kann ein Dialogfeld öffnen, das als Block beschrieben wird und ĂŒber zusĂ€tzliche Funktionen verfĂŒgt. Der Parameter 'SchaltflĂ€chen', der die SchaltflĂ€chen im Dialogfeld beschreibt. Der Client zeigt sofort die aktuellen Serverdaten und deren Änderungen an. Es werden nur vom Server geĂ€nderte Objekte gesendet. Um Ereignisse zu empfangen und deren Verarbeitung sicherzustellen, erstellen wir eine Websocket-Schicht (Framework), die Nachrichten automatisch in Aufrufe an Handler ĂŒbersetzt, die unseren Daten (Objekten) zugeordnet sind.

Die ganze Magie auf dem Server beruht auf der Tatsache, dass unsere angezeigten Daten so mit der Ebene verknĂŒpft werden sollten, dass ihre automatische Übersetzung in JSON gewĂ€hrleistet ist und Benachrichtigungen von BenutzeraktivitĂ€ten ohne Codierung zurĂŒckgerufen werden. Da dies von den FĂ€higkeiten einer bestimmten Sprache abhĂ€ngt, kann die Ebene fĂŒr jede Sprache unterschiedliche Optionen haben, sowohl architektonisch als auch spezifisch.

In einem Fall verfĂŒgt die Ebene beispielsweise ĂŒber einen Screenshot-Ordner, in dem jedes Modul eine Beschreibung eines Bildschirms in Python enthĂ€lt. Beim Start liest die Ebene die Bildschirme und gibt dem Benutzer eine mit globaler PrioritĂ€t = 0. Alle Daten werden automatisch mit jsonpickle ĂŒbertragen. Komplexe Elemente haben ihre eigene „Intelligenz“, wodurch dem Programmierer die Sorgfalt fĂŒr Details entzogen wird. Beispielsweise empfĂ€ngt eine Tabelle eine Reihe von Zeilen, in denen standardmĂ€ĂŸig die ID-Zeile fehlen kann, wenn die Anzahl der Daten in der Zeile == die Anzahl der Elemente in den Kopfzeilen ist. In diesem Fall sendet der Server die ID als ID an den Index in der Zeile, wenn der Benutzer eine Zeile auswĂ€hlt oder deren Inhalt bearbeitet. Wenn die Anzahl der Daten in der Zeile eins höher ist als in den Kopfzeilen, wird das letzte Element in den Zeilen als ID interpretiert und an den Server gesendet. Eine solche Automatisierung vereinfacht das Leben dort, wo Sie keine Einzelheiten benötigen, erheblich.Wenn es jedoch plötzlich benötigt wird, ist es am wenigsten arbeitsintensiv verfĂŒgbar.

Die Aufgabe, eine automatische Übersetzung in JSON in einem Format mit einer oder zwei Seiten bereitzustellen, ist in jeder Sprache vollstĂ€ndig lösbar (ich hoffe es).

Um die Anwendbarkeit dieses Ansatzes fĂŒr komplexe Anwendungen nicht zu diskutieren, finden Sie unten Screenshots, wie sie von uniGUI in Flattern geschrieben wurden. Die Wahl fiel auf mehrere Plattformen und das Fehlen zusĂ€tzlicher Schichten wie JS / Chrom. Im Flatter-Minus können Sie ekelhafte Desktop-UnterstĂŒtzung und geringe QualitĂ€t des Codes der oberen Ebene (GUI-Elemente) aufschreiben, eine unangenehme Architektur fĂŒr Punktaktualisierungen und das Verwalten von Elementen als Daten, die jedoch behandelt werden.



Der Nachrichtenfluss der GUI-App -> Server sieht ungefÀhr so aus:

Flattern: [Glossar, Begriffe, =, 658]
Flattern: [_Details, Links, @, @Folliculitis]
Flattern: [_Details, Links, @, @Adolescent]
Flattern: [Symbolleiste, _Back, =, _Back]
Flattern: [Symbolleiste, _Forward, =, _Forward]
Flattern: [Symbolleiste, _Back, =, _Back]
Flattern: [_Details, _Status, =, Virtual]
Flattern: [_Details, _Status , =, Stabil]
flattern: [_Details, Links, @,EntzĂŒndung]
flattern: [_Details, _Status, =, Virtual]
flattern: [_Details, _Status, =, Stable]
flattern: [toolbar, _Back, =, _Back]
flattern: [_Details, Links, @, @Folliculitis]

Wird es geben Verlangsamen Sie eine solche GUI, wenn Sie auf Ereignisse vom Server warten. Nein, da die GUI im Serverbenachrichtigungsmodus arbeitet und auf alle Benutzeraktionen als normale lokale GUI reagiert. StandardmĂ€ĂŸig wird die Serverstille bei Benutzeraktionen als OK betrachtet. Beim Wechseln der Bildschirme ist klar, dass die Beschreibung kommen sollte. Im Vergleich zur typischen eingebetteten GUI von App C kann es zu Verzögerungen kommen.

Gesamt. Mit aktuellen Tools ist es heute möglich, eine grafische BenutzeroberflĂ€che zu erstellen, die 90% des tristen Standard-Servicecodes entfernt und sich nicht darum kĂŒmmert, wo und wie sie funktionieren wird. Zumindest fĂŒr Business / Science-Anwendungen. Dieser Artikel ist ein Proof of Concept, dass das Erstellen eines bedingten App-Browsers nicht nur möglich, sondern auch notwendig ist.

All Articles