Salutations, collègues!
Il y a quelques mois, j'ai commencé à regarder Golang dans le but de l'utiliser pour des applications de bureau. J'ai aimé la langue, le volume et le sujet des paquets écrits pour cela, mais la situation avec l'interface graphique n'est pas si rose. Je ne m'attarderai pas sur les détails maintenant, il suffira de dire qu'après avoir lu quelques critiques et un rapide aperçu des packages GUI existants, j'ai décidé d'écrire le mien, d'autant plus que j'ai de l'expérience avec cela.
Ma première pensée a été de suivre le chemin déjà bien tracé: écrire un ensemble de fonctions correspondantes en C, ou plutôt en adapter une déjà prête - ce que j'ai écrit pour Harbor et C ++, le lier à l'aide de cgo (API C pour Golang) et emballage convivial. J'ai même commencé à le faire, j'ai reçu la première fenêtre, mais comme j'imaginais combien de travail restait à faire, séparément pour Windows, séparément pour Linux, un travail purement technique, puisque je l'avais déjà parcouru, mon enthousiasme s'était quelque peu calmé.
Et puis une autre idée est venue.
J'ai déjà une bibliothèque GUI, HwGUI for Harbor, qui est assez fonctionnelle, multi-plateforme, que j'utilise régulièrement pour mes applications. Tout ce dont j'ai besoin y est déjà implémenté. Pourquoi ne pas écrire sur sa base un programme qui fonctionne comme une sorte de serveur GUI. Après avoir démarré ce serveur, il écoutera silencieusement un port spécifique et, après avoir reçu une connexion de mon programme Golang, il créera des fenêtres, des widgets en réponse à ses demandes, les manipulera et fournira des commentaires lorsque des événements de widgets apparaissent - en un mot, implémenter une interface graphique pour cela. Tous les détails de bas niveau de l'implémentation GUI sont déjà dans la bibliothèque, pour Windows - via des appels directs à WinAPI, pour Linux / Unix et, probablement, macOs - via GTK. De plus, je n'ai pas l'intention de créer un serveur au sens plein du terme, il n'acceptera pas les connexions de différents programmes - cela introduirait des difficultés supplémentaires inutiles. Pour chaque instance du programme Golang, une instance distincte du serveur GUI sera lancée, ce qui simplifie encore la tâche. En général, le programme se composera donc de deux processus, dont l'un exécute la tâche principale, l'autre est responsable de l'interface.
Le package correspondant pour Go doit inclure la procédure Init, qui démarre le serveur GUI et le joint, ainsi qu'un ensemble de structures, méthodes, fonctions pour créer des fenêtres et des widgets et les manipuler. Le contenu principal de toutes ces fonctions est d'envoyer des messages d'un certain format (basé sur JSON) au serveur et d'en recevoir des messages. La communication est prise en charge à l'aide de deux ports TCP / IP, l'un est responsable de l'envoi des demandes au serveur, l'autre est responsable de la réception des signaux du serveur pour le traitement des événements (cliquer sur un bouton, fermer une fenêtre, etc.). La tâche est relativement simple, le package lui-même est petit. Pas besoin d'utiliser cgo, pas besoin de se lier à des bibliothèques tierces, tout le code en pur Go. Le fichier exécutable du programme lui-même et le fichier exécutable du serveur GUI sont tous.
Le choix de Harbor + HwGUI pour l'implémentation du serveur GUI pour moi est principalement dû au fait que ce sont mes outils «natifs», la solution la plus simple et la plus rapide. Mais c'est un bon choix à d'autres points de vue. Voici, à mon avis, les principaux avantages:
- multiplateforme «dans la boîte»;
- ce qu'on appelle l'aspect et la convivialité natifs, car sous Windows, il s'agit exclusivement d'appels WinAPI, sous Linux / Unix - GTK; combien le GTK «natif» pour macOs je ne sais vraiment pas;
- la possibilité d'utiliser Harbor comme langage de script intégré, des fragments de code pour l'exécution peuvent être transférés au serveur - des gestionnaires d'événements, par exemple, qui peuvent décharger le programme principal de certains détails d'implémentation. De plus, Harbor est bon pour beaucoup de choses, pour travailler avec dbf et certaines bases de données, par exemple;
- mise en œuvre de l'impression;
- la possibilité d'utiliser des formulaires d'écran créés par le concepteur (utilitaire HwGUI). Ces formulaires sont stockés au format XML et peuvent être utilisés sans modification dans n'importe quel système d'exploitation dans lequel le serveur fonctionne;
- la possibilité d'utiliser des formulaires de rapport créés par le même concepteur pour l'impression (également en XML).
Bref, j'ai commencé à le faire et une partie importante du travail est déjà terminée. Les deux projets, GuiServer et le framework GUI externe de Golang sont sur Github, tous les liens sont à la fin de l'article. Voici quelques captures d'écran. Rien de spécial, juste des tests.
Il s'agit d'une simple boîte de dialogue:
Et cela se fait sur la base d'un exemple tiré du livre de Kernigan et Donovan:
Désormais, l'objectif principal des projets est de faire en sorte que ce joli couple, External et GuiServer, puisse faire tout ce que HwGUI peut faire. Eh bien, dans le processus de création de vraies applications à l'aide d'Externe, il sera clair ce qui est le plus nécessaire.
Cela pourrait être la fin, j'ai reporté la description du paquet Golang pour une autre fois. Mais l'essentiel de cet article ne fait que commencer. Après tout, la méthode décrite pour implémenter un framework GUI avec le même serveur GUI peut être utilisée pour d'autres langues. C, Python, Java, ..., même Perl et PHP (et pourquoi pas?) - voir le titre de l'article. Coûts minimaux - et une solution graphique assez fonctionnelle est prête. La chose la plus difficile pour chaque langue spécifique n'est pas la mise en place d'un échange avec le serveur, mais que cette solution s'inscrit organiquement dans son paradigme, dans sa logique interne. Si quelqu'un veut créer un tel cadre pour sa langue, j'essaierai de fournir toute l'assistance possible pour obtenir les informations nécessaires et, éventuellement, pour ajouter certaines fonctionnalités au serveur GUI.
En parallèle avec le package Golang, j'ai fait un analogue pour Harbor, principalement à des fins de vérification / débogage. Il est peu probable que je fasse un framework pour Perl, mais pour C ou C ++ c'est très probable. Et voici pourquoi: après tout, il existe une autre fonctionnalité intéressante liée à l'utilisation d'un serveur GUI, il peut être exécuté sur un autre ordinateur. Le programme principal s'exécute sur un ordinateur et son interface sur un autre. Immédiatement vu ici sont des options pour utiliser ce cas:
- le programme principal s'exécute sur un serveur Linux / Unix sur lequel le shell graphique n'est pas installé du tout;
- le programme principal s'exécute sur l'ordinateur de quelqu'un d'autre (avec un comptable conditionnel dans votre entreprise) et vous, sans interférer avec lui, le gérez par vous-même;
- le programme principal s'exécute sur un smartphone, et vous creusez dans ses entrailles à partir d'un ordinateur normal;
- le programme principal s'exécute sur le contrôleur, sur certains Arduino, Raspberry ou leurs homologues, où il peut n'y avoir aucun moniteur normal. Connectez-vous avec votre ordinateur portable - et c'est parti.
Eh bien, pour cette dernière option, un framework C pour un serveur GUI serait probablement utile, je pense que cette possibilité est très prometteuse.
Et enfin, les liens:
github.com/alkresin/guiserver - GuiServer sur Github
github.com/alkresin/external - Externe (package Go) sur Github
www.kresin.ru/guisrv.html - la page
GuiServer sur mon site, ici vous pouvez télécharger des binaires prêts à l'emploi
habr.com/post/198618 - mon article sur Harbour est ici sur Habré
en.wikipedia.org/wiki/Harbor - Harbour sur Wikipédia
www.kresin.ru/harbour.html - page Harbour sur mon site Web
www.kresin.ru/hwgui.html - la page HwGUI sur mon site Web
PS: Il est clair que peu de gens installeront Harbour et HwGUI pour construire GuiServer à partir des sources, donc je poste régulièrement les binaires collectés sur la page GuiServer sur mon site - pour Windows, Debian 8 32 bits, Ubuntu 18.04 64 bits. Je peux assembler pour Fedora, mais sous macOs - hélas, je ne l'ai pas à distance de marche.