Saludos, colegas!
Hace un par de meses, comencé a mirar Golang con el objetivo de usarlo para aplicaciones de escritorio. Me gustó el idioma, el volumen y el tema de los paquetes escritos para él causaron impresión, pero la situación con la GUI no es tan optimista. No me detendré en los detalles ahora, será suficiente decir que después de leer algunas reseñas y un vistazo rápido a los paquetes de GUI existentes, decidí escribir el mío, especialmente porque tengo experiencia en esto.
Lo primero que pensé fue ir por el camino ya recorrido: escribir un conjunto de funciones correspondientes en C, o más bien, adaptar una ya lista: lo que una vez escribí para Harbor y C ++, vincularlo usando cgo (C API para Golang) y Envoltorio amigable. Incluso comencé a hacer esto, recibí la primera ventana, pero cuando imaginé cuánto trabajo me quedaba por delante, por separado para Windows, por separado para Linux, trabajo puramente técnico, ya que ya lo había pasado, mi entusiasmo se había enfriado un poco.
Y entonces surgió otra idea.
Después de todo, ya tengo una biblioteca GUI, HwGUI for Harbor, que es bastante funcional, multiplataforma, que uso regularmente para mis aplicaciones. Todo lo que necesito ya está implementado en él. ¿Por qué no escribir sobre una base un programa que funciona como una especie de servidor GUI? Después de iniciar este servidor, escuchará en silencio un puerto específico, y después de recibir una conexión de mi programa Golang, creará ventanas, widgets en respuesta a sus solicitudes, los manipulará y proporcionará comentarios cuando aparezca cualquier evento de widgets, en una palabra, implementar una GUI para ello. Todos los detalles de bajo nivel de la implementación de la GUI ya están en la biblioteca, para Windows, a través de llamadas directas a WinAPI, para Linux / Unix y, probablemente, macOs, a través de GTK. Además, no tengo la intención de hacer un servidor en el sentido completo de la palabra, no aceptará conexiones de diferentes programas, esto introduciría dificultades adicionales innecesarias. Para cada instancia del programa Golang, se lanzará una instancia separada del servidor GUI, lo que simplifica aún más la tarea. En general, el programa consistirá en dos procesos, uno de los cuales realiza la tarea principal, el otro es responsable de la interfaz.
El paquete correspondiente para Go debe incluir el procedimiento Init, que inicia el servidor GUI y lo une, y un conjunto de estructuras, métodos, funciones para crear ventanas y widgets y manipularlos. El contenido principal de todas estas funciones es enviar mensajes de cierto formato (basado en JSON) al servidor y recibir mensajes de él. La comunicación se admite mediante dos puertos tcp / ip, uno es responsable de enviar solicitudes al servidor, el otro es responsable de recibir señales del servidor para el procesamiento de eventos (presionar un botón, cerrar una ventana, etc.). La tarea es relativamente simple, el paquete en sí es pequeño. No es necesario usar cgo, no es necesario vincular a bibliotecas de terceros, todo el código en puro Go. El archivo ejecutable del programa en sí y el archivo ejecutable del servidor GUI son todos.
La elección de Harbor + HwGUI para la implementación del servidor GUI para mí se debe principalmente al hecho de que estas son mis herramientas "nativas", la solución más simple y rápida. Pero esta es una buena opción desde otros puntos de vista. Aquí, en mi opinión, las principales ventajas:
- multiplataforma "en la caja";
- lo que se llama apariencia nativa, ya que bajo Windows es exclusivamente llamadas WinAPI, bajo Linux / Unix - GTK; cuánto realmente desconozco el GTK "nativo" para macOs;
- la capacidad de usar Harbour como un lenguaje de script incorporado, puede transferir fragmentos de código para su ejecución al servidor, por ejemplo, controladores de eventos, que pueden descargar el programa principal de algunos detalles de implementación. Además, Harbor es bueno para muchas cosas, para trabajar con dbf y algunas bases de datos, por ejemplo;
- implementación de impresión;
- la capacidad de usar formularios de pantalla creados por el Diseñador (utilidad HwGUI). Estos formularios se almacenan en formato XML y se pueden usar sin cambios en ningún sistema operativo en el que se ejecuta el servidor;
- la capacidad de usar formularios de informes creados por el mismo Diseñador para imprimir (también en XML).
En resumen, comencé a hacer esto y una parte importante del trabajo ya se ha completado. Ambos proyectos, GuiServer y el marco de GUI externo de Golang están en Github, todos los enlaces están al final del artículo. A continuación hay un par de capturas de pantalla. Nada especial, solo pruebas.
Este es un cuadro de diálogo simple:
Y esto se hace en base a un ejemplo del libro de Kernigan y Donovan:
Ahora, el objetivo principal de los proyectos es garantizar que esta dulce pareja, externa y GuiServer, pueda hacer todo lo que HwGUI puede hacer. Bueno, en el proceso de crear algunas aplicaciones reales usando Externo, quedará claro qué se necesita más.
Este podría ser el final, pospuse la descripción del paquete Golang para otro momento. Pero lo principal en este artículo está recién comenzando. Después de todo, el método descrito para implementar un marco GUI con el mismo servidor GUI se puede usar para otros idiomas. C, Python, Java, ..., incluso Perl y PHP (¿y por qué no?) - vea el título del artículo. Costos mínimos, y una solución GUI bastante funcional está lista. Lo más difícil para cada idioma específico no es la implementación de un intercambio con el servidor, sino que esta solución se ajusta orgánicamente a su paradigma, a su lógica interna. Si alguien quiere crear dicho marco para su idioma, intentaré brindar toda la asistencia posible para obtener la información necesaria y, posiblemente, para agregar algunas funciones al servidor GUI.
En paralelo con el paquete Golang, hice un análogo para Harbour, principalmente con fines de verificación / depuración. Es poco probable que haga un marco para Perl, pero para C o C ++ es bastante probable. Y he aquí por qué: después de todo, hay otra característica interesante relacionada con el uso de un servidor GUI, que se puede ejecutar en otra computadora. El programa principal se ejecuta en una computadora y su interfaz en otra. Inmediatamente visto aquí hay opciones para usar este caso:
- el programa principal se ejecuta en un servidor Linux / Unix en el que el shell gráfico no está instalado en absoluto;
- el programa principal se ejecuta en la computadora de otra persona (con un contador condicional en su empresa) y usted, sin interferir con él, lo administra por su cuenta;
- el programa principal se ejecuta en un teléfono inteligente y usted profundiza en su interior desde una computadora normal;
- el programa principal se ejecuta en el controlador, en algunos Arduino, Raspberry o sus contrapartes, donde puede que no haya un monitor normal. Conéctese con su computadora portátil y listo.
Bueno, para esta última opción, un C-framework para un servidor GUI probablemente sería útil, creo que esta posibilidad es muy prometedora.
Y finalmente, los enlaces:
github.com/alkresin/guiserver - GuiServer en Github
github.com/alkresin/external - Externo (paquete Go) en Github
www.kresin.ru/guisrv.html - la página de
GuiServer en mi sitio, aquí puede descargar binarios listos para usar
habr.com/post/198618 - mi artículo sobre Harbour está aquí en Habré
en.wikipedia.org/wiki/Harbor - Puerto en Wikipedia
www.kresin.ru/harbour.html - Página de puerto en mi sitio web
www.kresin.ru/hwgui.html : la página HwGUI de mi sitio web
PD: está claro que pocas personas instalarán Harbour y HwGUI para ensamblar GuiServer desde la fuente, por lo que publico regularmente los binarios recopilados en la página de GuiServer en mi sitio, para Windows, Debian 8 de 32 bits, Ubuntu 18.04 de 64 bits. Puedo ensamblar para Fedora, pero bajo macOs, por desgracia, no lo tengo a poca distancia.