GUI universelle ~ = fin Ă  la misĂšre

Pour moi, l'interface graphique idéale est une application qui ne nécessite pas de programmation, de conception, de maintenance et est capable de fonctionner de maniÚre égale avec n'importe quel langage et sur n'importe quelle plate-forme sans aucun réglage. Est-il possible de notre vivant que nous essayions de le comprendre.

Il est facile d'apprendre individuellement quelque chose de Vue / React, JavaFX, Python PyQt, ... mais obtenir des donnĂ©es et interagir avec le zoo du logiciel de maniĂšre simple et Ă©lĂ©gante sans penser Ă  l'utilisateur-OS / navigateurs / plates-formes est une tĂąche non rĂ©solue pour ces outils. Je ne veux pas entrer dans le nouveau cadre (mĂȘme l'ancien, oubliĂ©), changer le langage de programmation, ratisser le rĂąteau et me boucher la tĂȘte avec des ordures. Je veux programmer exactement ma tĂąche, sans ĂȘtre distrait par la lutte avec toutes sortes de frameworks GUI. Et j'ai trouvĂ© une solution pour moi.

En tant que protocole d'échange, nous utiliserons Json comme premier format en termes de popularité / compréhensibilité / lisibilité / prise en charge de tous les langages de programmation à un degré ou un autre.

Le serveur envoie des données Json, selon lesquelles l'interface graphique de notre application doit concevoir une image qui satisfait les spécifications d'une belle interface graphique. Google avec son Material Design est aujourd'hui la norme, alors prenez-le.

Les exigences pour une interface graphique moderne incluent la présence d'éléments standard, tels que des boutons, des champs de saisie, des tableaux, etc. Estimons comment utiliser l'ensemble minimal de conventions pour indiquer à l'interface graphique que nous avons besoin de certains éléments à l'écran. En voici les principaux:

  • Bouton sans Ă©tat {'name': 'Push me'}. Si l'Ă©lĂ©ment ne contient qu'un nom, alors c'est un bouton.
  • Le champ de saisie est {'name': 'Edit me', 'value': ''} car la valeur de type est une chaĂźne.
  • Le bouton du sĂ©lecteur est {'name': 'My state', 'value': false} car le type false est boolĂ©en.
  • SĂ©lectionnez dans la liste {'nom': 'Changer quelque chose', valeur: 'choix1', options = ['choix1', 'choix2', 'choix3']}
  • {‘name’:’Image, ‘url'’: ’..’, ‘width’: .., ‘height’:
 }
  • {‘name’:’My table’, 'headers'=[‘Name’, ‘Synonym’], rows = [
    [‘young’, ‘youthful’],
    [‘small’, ‘ meager’],
    ...]
    }

Pour la personnalisation, vous pouvez dĂ©finir le type d'Ă©lĂ©ment sur {type: 'ButtonSwitcher'} si le type sĂ©lectionnĂ© automatiquement par JSON ne vous convient pas. Cela est possible lorsque le mĂȘme JSON peut ĂȘtre affichĂ© de plusieurs maniĂšres. Par exemple, «SĂ©lectionner dans une liste» peut ĂȘtre reprĂ©sentĂ© comme un champ de saisie avec une liste dĂ©roulante, ou il peut Ă©galement s'agir d'un ensemble horizontal de boutons, dont l'un est actif et correspond Ă  la valeur actuelle.

Avec un petit nombre d'options, il est logique d'utiliser automatiquement l'option de bouton, avec un grand nombre (plus de 3) - un champ de sĂ©lection d'entrĂ©e. Notre interface graphique elle-mĂȘme choisit la meilleure façon de rendre, mais si vous en avez vraiment besoin - tapez: ... pour vous aider. Normalement, le type n'est pas nĂ©cessaire et le concepteur automobile doit faire face Ă  lui-mĂȘme.

Complétons l'image en détail:

  • si le nom ne doit pas s'afficher Ă  l'Ă©cran, il doit commencer par _;
  • - , ‘icon’: ‘ Material Design ’; push - {‘name’: ‘_Check’, ‘icon’: ‘check’}
  • , Viewers, , ‘colors’, ‘params’,
 // . — , .

Pour le regroupement logique des éléments, nous introduisons le concept d'un bloc qui regroupe les éléments logiquement liés dans un bloc visuel.

{'name': 'Block 1', 'elems': [{'name': '_Check', 'icon': 'check'}, ...]}
Dans le bloc, tous les éléments doivent avoir des noms uniques, car ils sont id .

Normalement, les blocs sont construits horizontalement s'ils ne peuvent pas tout contenir sur l'Ă©cran (ils ont dĂ©marrĂ© l'interface graphique de l'application sur un mobile, par exemple), le concepteur automatique les masque, mais ajoute des icĂŽnes Ă  la barre d'outils pour les ouvrir d'un simple toucher. Cela vous donne la possibilitĂ© de travailler avec une interface graphique complexe, mĂȘme sur de petits Ă©crans.

Le premier niveau de description est l'écran. Il ressemble à {'name': 'Screan', les blocs: [..], le menu: [{'name': 'Screen', 'icon': ..,}, ..], 'toolbar': [JSON set - éléments (boutons, champs, etc.)]}

Ajoutez les détails d'implémentation de l'uniGUI conditionnel qui prend en charge notre protocole JSON. Il s'agit d'un processus distinct qui communique avec le serveur de données Websocket et fournit l'affichage de ses données avec un rapport ultérieur de toutes les mises à jour de ces données qui sont importantes pour le serveur.

Lors de la connexion au serveur, uniGUI s'attend Ă  recevoir Screen. AprĂšs l'avoir reçue, il conçoit et dessine les informations rĂ©sultantes de maniĂšre optimale pour l'Ă©cran actuel de l'utilisateur, puis il attend une rĂ©action de l'utilisateur et du serveur. À partir de l'image de donnĂ©es construite, le serveur reçoit un flux de messages JSON qui dĂ©crivent entiĂšrement ce que l'utilisateur a fait. Ils ont la forme ['Block', 'Elem', 'type of action', 'value'], oĂč 'Block' et 'Elem' sont les noms du bloc et de l'Ă©lĂ©ment, value est la valeur de l'Ă©vĂ©nement.

Le serveur peut soit accepter la modification, soit les annuler en envoyant une fenĂȘtre d'informations sur l'Ă©cart. Il peut ouvrir une boĂźte de dialogue, qui est dĂ©crite comme un bloc, et en a d'autres. le paramĂštre «boutons», qui dĂ©crit les boutons de la boĂźte de dialogue. Le client affiche instantanĂ©ment les donnĂ©es actuelles du serveur et leurs modifications. Seuls les objets modifiĂ©s par le serveur sont envoyĂ©s. Pour recevoir les Ă©vĂ©nements et assurer leur traitement, nous allons crĂ©er une couche Websocket (framework), qui traduira automatiquement les messages en appels aux gestionnaires associĂ©s Ă  nos donnĂ©es (objets).

Toute la magie du serveur se rĂ©sume au fait que nos donnĂ©es affichĂ©es doivent ĂȘtre liĂ©es Ă  la couche de maniĂšre Ă  assurer leur traduction automatique en JSON et Ă  rappeler les notifications de l'activitĂ© de l'utilisateur sans aucun codage. Comme cela dĂ©pend des capacitĂ©s d'un langage particulier, pour chaque langue, la couche peut avoir diffĂ©rentes options, Ă  la fois architecturales et spĂ©cifiques.

Par exemple, dans un cas, la couche a un dossier de captures d'Ă©cran, chacun des modules dans lequel a une description d'un Ă©cran en Python. Au dĂ©marrage, la couche lit les Ă©crans, donne Ă  l'utilisateur une prioritĂ© globale = 0. Toutes les donnĂ©es sont transmises automatiquement Ă  l'aide de jsonpickle. Les Ă©lĂ©ments complexes ont leur propre «intelligence», supprimant le soin des dĂ©tails du programmeur. Par exemple, une table reçoit un ensemble de lignes dans lesquelles, par dĂ©faut, la ligne id peut ĂȘtre absente lorsque le nombre de donnĂ©es dans la ligne == le nombre d'Ă©lĂ©ments dans les en-tĂȘtes. Dans ce cas, lorsque l'utilisateur sĂ©lectionne une ligne ou modifie son contenu, le serveur envoie l'identifiant Ă  l'index en ligne comme identifiant ee. Si le nombre de donnĂ©es dans la ligne est supĂ©rieur Ă  celui des en-tĂȘtes, le dernier Ă©lĂ©ment des lignes est interprĂ©tĂ© comme id et c'est lui qui est envoyĂ© au serveur. Une telle automatisation simplifie considĂ©rablement la vie lĂ  oĂč vous n'avez pas besoin de dĂ©tails,mais si vous en avez soudainement besoin, il est disponible de la maniĂšre la moins laborieuse.

La tùche de fournir une traduction automatique en JSON, suivant un format qui occupe une ou deux pages, est complÚtement résolu dans n'importe quelle langue (je l'espÚre).

Afin de ne pas discuter de l'applicabilité de cette approche pour des applications complexes, voici des captures d'écran telles que décrites par uniGUI écrites en flutter. Le choix s'est porté sur lui pour les multi-plateformes et le manque de couches supplémentaires comme JS / chrome. Dans le flutter moins, vous pouvez noter la prise en charge dégoûtante du bureau et la faible qualité du code de la couche supérieure (éléments GUI), une architecture désagréable pour les mises à jour ponctuelles et la gestion des éléments en tant que données, qui, cependant, est traitée.



L'interface graphique de l'application de flux de messages -> serveur ressemble Ă  ceci:

flutter: [Glossaire, termes, =, 658]
flutter: [_Details, Links, @, @Folliculitis]
flutter: [_Details, Links, @, @Adolescent]
flutter: [toolbar, _Back, =, _Back]
flutter: [toolbar, _Forward, =, _Forward]
flutter: [toolbar, _Back, =, _Back]
flutter: [_Details, _Status, =, Virtual]
flutter: [_Details, _Status , =, Stable]
flottement: [_DĂ©tails, Liens, @,Inflammation]
flutter: [_Details, _Status, =, Virtual]
flutter: [_Details, _Status, =, Stable]
flutter: [toolbar, _Back, =, _Back]
flutter: [_Details, Links, @, @Folliculitis] Y

aura-t-il ralentissez une telle interface graphique lorsque vous attendez des événements du serveur. Non, car l'interface graphique fonctionne en mode de notification du serveur, réagissant à toutes les actions de l'utilisateur comme une interface graphique locale normale. Par défaut, il considÚre le silence du serveur sur les actions des utilisateurs comme OK. Lors du changement d'écrans, il est clair que sa description doit venir. Il peut y avoir un délai par rapport à l'interface graphique intégrée de l'application c typique.

Total. Il est possible aujourd'hui, sur les outils actuels, de crĂ©er une interface graphique qui supprime 90% du code de service morne standard et sans se soucier oĂč et comment cela fonctionnera. Au moins pour les applications commerciales / scientifiques. Cet article est une preuve de concept que la crĂ©ation d'un navigateur d'application conditionnel est non seulement possible, mais nĂ©cessaire.

All Articles