Externe - GUI pour Golang

Salutations, collègues!

Il y a environ un mois, j'ai publié un article ici sur les cadres GUI - un fil qui a suggéré la technologie pour créer des cadres GUI pour différents langages de programmation, basée sur la connexion (tcp / ip ou autre) à un processus externe qui joue le rôle d'une sorte de serveur GUI. Ici, je veux présenter une mise en œuvre concrète de cette idée - un nouveau cadre GUI pour Golang - Externe .

Pourquoi était-il nécessaire d'écrire une nouvelle interface graphique pour Golang , s'il existe déjà de nombreux outils de ce type? D'abord parce qu'aucun d'eux ne me convenait pleinement. Il fallait quelque chose pour créer des applications de bureau, multiplateforme, pour avoir l'air naturel pour chaque plate-forme. Si possible, pas très encombrant, avec un minimum de dépendances - je me suis engagé dans une approche minimaliste.

J'ai été guidé par cette liste . Deux positions - application et marche ont été immédiatement barrées car ne répondant pas aux exigences de la multiplateforme. Après réflexion, il a rejeté ceux basés sur html / css / javascript. Premièrement, il me semble quelque peu inhabituel de créer une application de bureau en tant que page Web et, deuxièmement, ils entraînent des moteurs assez lourds avec eux. Ainsi, par exemple, go-astilectron et gowd sont basés sur Electron et nw.js , respectivement, et ceux-ci, à leur tour, sont basés sur node.js. Imaginez combien tout doit être installé par l'utilisateur final pour exécuter même un petit utilitaire? A moins que go-sctiter ne semble préférable de ce point de vue: le Sciter qui se tient derrière n'est pas si monstrueux.

Go-gtk et gotk3 sont basés sur GTK. Ce sont, apparemment, des paquets bien faits, mais je les ai également refusés, car, à mon avis, l'utilisation de GTK sous Windows n'est pas la meilleure solution. Les fenêtres GTK ne semblent pas natives sous Windows. La liaison Qt est une chose puissante, bien sûr, mais plutôt compliquée, et les dimensions ... Quand je lis: "Vous avez également besoin de 2,5 Go de RAM libre (qui n'étaient nécessaires que lors de la configuration initiale) et d'au moins 5 Go d'espace disque libre", les derniers doutes ont disparu. Go lui-même prend dix fois moins d'espace. Et puis il y a des restrictions de licence: «cette liaison avec sa licence LGPL ne convient pas pour être utilisée dans une application de source fermée destinée à être distribuée au grand public».

Que nous reste-t-il de la liste? L'interface utilisateur peut être une bonne option, mais elle est toujours au stade mi-alpha. Fyne a également l'air plutôt bien, mais ne semble pas tout à fait prêt. Il était quelque peu gênant que, d'une part, "Fyne soit entièrement construit à l'aide de graphiques vectoriels", et, d'autre part, "les packages Windows EFL sont actuellement beaucoup plus anciens, de sorte que vous ne verrez pas les parties graphiques vectorielles des applications Fyne" - comme ceci. Eh bien, je n'aime pas ça pour installer EFL (la bibliothèque graphique sur laquelle Fyne est basé) sous Windows, vous avez besoin de MSYS .

En bref, avec tout le respect que je dois aux auteurs de ces packages et aux produits de leur travail, je n'ai rien choisi pour moi et, en toute conscience, j'ai procédé à ce que je voulais faire - écrire un nouveau cadre GUI - Externe .

Comme je l'ai écrit dans un article précédent, External n'implémente pas les éléments GUI seul, il utilise une application distincte pour cela, un processus distinct agissant comme un serveur GUI, cette application est appelée GuiServer . External le lance, le rejoint via tcp / ip, envoie des commandes / requêtes pour créer des fenêtres et des widgets, les manipuler, etc., et en reçoit des messages.

Voici un programme simple qui crée une fenêtre avec l'inscription traditionnelle Hello, world:

package main import egui "github.com/alkresin/external" func main() { if egui.Init("") != 0 { return } pWindow := &egui.Widget{X: 100, Y: 100, W: 400, H: 140, Title: "My GUI app"} egui.InitMainWindow(pWindow) pWindow.AddWidget(&egui.Widget{Type: "label", X: 20, Y: 60, W: 160, H: 24, Title: "Hello, world!" }) pWindow.Activate() egui.Exit() } 

La fonction Init () démarre GuiServer et le rejoint. Un paramètre de chaîne peut lui être transmis, qui détermine, si nécessaire, le nom de GuiServer et son chemin, son adresse IP et son port, ainsi que le niveau de journalisation.

InitMainWindow () crée la fenêtre principale de l'application avec les paramètres spécifiés. Méthode AddWidget () - Ajoute un widget de type étiquette.

Activer () - affiche une fenêtre à l'écran et met le programme en mode veille.
Les fenêtres et les widgets sont définis dans la structure Widget - je n'ai pas fait de structures distinctes pour chaque objet, car Je n'ai pas trouvé de moyen pratique d'implémenter cela, étant donné que Go n'a pas d'héritage. Cette structure comprend des champs communs à la plupart des widgets et une chaîne de mappage [chaîne], qui contient des propriétés spécifiques à un objet particulier:

 type Widget struct { Parent *Widget Type string Name string X int [...] Font *Font AProps map[string]string aWidgets []*Widget } 

Les méthodes de cette structure incluent le AddWidget () familier, ainsi que SetText (), SetImage (), SetParam (), SetColor (), SetFont (), GetText (), Move (), Enable (), etc. Je voudrais mentionner SetCallBackProc () et SetCallBackFunc () - pour définir les gestionnaires d'événements.
Il serait inapproprié de lister ici toutes les fonctions, structures et méthodes, pour cela il y en a plus précisément. il doit y avoir de la documentation. Je n'en dirai que quelques-uns pour donner une idée générale:

Menu (), MenuContext (), EndMenu (), AddMenuItem (), AddMenuSeparator () - un ensemble de fonctions pour créer un menu, principal ou contextuel.
EvalProc (chaîne sCode), EvalFunc (chaîne sCode) transmet un fragment de code Harbour (plusieurs lignes peut être) pour exécution sur GuiServer - une sorte d'implémentation du langage de script intégré.
OpenForm (chaîne sPath) - crée une fenêtre basée sur la description du fichier xml créé par HwGui Designer.
OpenReport (chaîne sPath) - imprime un rapport basé sur la description du fichier xml créé par HwGui Designer.
MsgInfo (), ..., SelectFile (), SelectColor (), SelectFont () - appeler les boîtes de dialogue et les boîtes de dialogue standard.
InitPrinter () et un ensemble de méthodes de structure d'imprimante: Say (), Box (), Line (), etc. fournissent une impression à l'imprimante avec la possibilité de prévisualiser.

Voici la liste complète des widgets actuellement pris en charge:
étiquette, modifier, bouton, vérifier, radio, radiogr, groupe, combo, bitmap, ligne, panneau (conçu pour héberger d'autres widgets dessus), paneltop, panelbot, ownbtn (bouton dessiné par le propriétaire), séparateur, mise à jour, arbre, progression, onglet, parcourir (tableau, comme beaucoup l'appellent), cedit (modifier avec des fonctionnalités avancées), monthcal.

Tous sont répertoriés dans la fonction init () de extwidg.go avec des propriétés supplémentaires. accessible pour chacun d'eux - ces propriétés sont définies via Widget.AProps. Beaucoup de ces widgets ont d'autres propriétés, en particulier une navigation riche en eux; ils peuvent être définis séparément à l'aide de la méthode SetParam ().

Externe s'est avéré être de petit volume, il est écrit en pur Go , il ne tire pas d'autres paquets sauf quelques standards. La multiplateforme est fournie par GuiServer , qui peut être compilé sous Windows, Linux / Unix, Mac OS. Un certain inconvénient est associé précisément à la nécessité d'utiliser ce module externe, que vous devez soit compiler à partir des sources, soit télécharger celui terminé sur mon site et le placer dans le répertoire spécifié dans PATH. Soit dit en passant, il est petit - seulement environ un mégaoctet et demi pour Windows et environ trois - pour Linux.

À quoi cela ressemble, je vais vous montrer un exemple d'une petite application ETutor - le tutoriel Golang. Ce programme présente une collection de fragments de code sur Go sous la forme d'une arborescence. Le code peut être édité, exécuté pour exécution. Rien de spécial, mais assez confortable. La collection peut être réapprovisionnée, ajoutez de nouvelles collections. Maintenant, il y a collecté (pas encore complètement) A Tour of Go, Go by Example et plusieurs exemples sur External lui-même. ETutor peut également être utilisé pour, par exemple, organiser un ensemble d'utilitaires sur Go. Donc, des captures d'écran.

Windows 10:



Debian, Gnome:



Et enfin, les liens:

Externe sur Github
GuiServer sur Github
ETutor sur Github
Une page sur GuiServer sur mon site Web où vous pouvez télécharger des binaires prêts à l'emploi
https://groups.google.com/d/forum/guiserver - Un groupe pour discuter de tous les problèmes liés à GuiServer et à External
Article sur GuiServer sur Habré

Source: https://habr.com/ru/post/fr431490/


All Articles