Saludos, colegas!
Hace aproximadamente un mes, publiqué un artículo sobre los
marcos de GUI aquí, en un hilo , que ofrecía la tecnología para crear marcos de GUI para diferentes lenguajes de programación, basado en la conexión (tcp / ip u otro) a un proceso externo que desempeña el papel de un tipo de servidor de GUI. Aquí quiero presentar una implementación concreta de esta idea: un nuevo marco GUI para
Golang -
Externo .
¿Por qué fue necesario escribir una nueva GUI para
Golang , si ya hay muchas herramientas disponibles? En primer lugar, porque ninguno de ellos me convenía al máximo. Se necesitaba algo para crear aplicaciones de escritorio, multiplataforma, para lucir natural para cada plataforma. Si es posible, no muy voluminoso, con un mínimo de dependencias, estoy comprometido con un enfoque minimalista.
Me guié
por esta lista . Dos posiciones: la
aplicación y la
caminata se tacharon inmediatamente por no cumplir con los requisitos de la plataforma cruzada. Después de pensarlo un poco, rechazó los basados en html / css / javascript. En primer lugar, me parece algo inusual construir una aplicación de escritorio como página web y, en segundo lugar, arrastran motores bastante pesados con ellos. Entonces, por ejemplo,
go-astilectron y
gowd se basan en
Electron y
nw.js , respectivamente, y estos, a su vez, se basan en
node.js. ¿Imagina cuánto debe instalar todo el usuario final para ejecutar incluso una pequeña utilidad? A menos que
go-sctiter parezca preferible desde este punto de vista: el
Sciter parado detrás de él no
es tan monstruoso.
Go-gtk y
gotk3 se basan en GTK. Aparentemente, estos son paquetes completos, pero también los rechacé, porque, en mi opinión, usar GTK en Windows no es la mejor solución. Las ventanas GTK no parecen nativas en Windows.
Qt vinculante es algo poderoso, por supuesto, pero bastante complicado, y las dimensiones ... Cuando leí: "También necesitas 2.5 GB de RAM libre (que solo se necesita durante la configuración inicial) y al menos 5 GB de espacio libre en el disco", las últimas dudas desaparecieron. Ir en sí ocupa diez veces menos espacio. Y luego hay restricciones de licencia: "este enlace con su licencia LGPL no es adecuado para usarse en aplicaciones de código cerrado que están destinadas a ser distribuidas al público en general".
¿Qué nos queda de la lista?
La interfaz de usuario puede ser una buena opción, pero todavía está en la etapa alfa central.
Fyne también se ve bastante bien, pero no parece estar listo. Fue un poco vergonzoso que, por un lado, "Fyne esté construido completamente con gráficos vectoriales" y, por otro, "los paquetes de Windows EFL son actualmente mucho más antiguos, por lo que no verá las porciones de gráficos vectoriales de las aplicaciones de Fyne", como esta. Bueno, no me gusta eso para instalar
EFL (la biblioteca gráfica en la que se basa
Fyne ) en Windows, necesita
MSYS .
En resumen, con el debido respeto a los autores de estos paquetes y a los productos de su trabajo, no elegí nada por mí mismo y, con la conciencia tranquila, procedí a lo que quería hacer: escribir un nuevo marco GUI -
Externo .
Como ya escribí en el artículo anterior,
Externo no implementa elementos GUI por sí solo, usa una aplicación separada para esto, un proceso separado que actúa como un servidor GUI, esta aplicación se llama
GuiServer .
External lo inicia, lo une a través de tcp / ip, envía comandos / solicitudes para crear ventanas y widgets, manipularlos, etc., y recibe mensajes de él.
Aquí hay un programa simple que crea una ventana con la inscripción tradicional Hola, mundo:
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 función Init () inicia
GuiServer y se une a ella. Se le puede pasar un parámetro de cadena, que determina, si es necesario, el nombre de
GuiServer y su ruta, dirección IP y puerto, y el nivel de registro.
InitMainWindow () crea la ventana principal de la aplicación con los parámetros especificados. Método AddWidget (): agrega un widget de etiqueta de tipo.
Activar (): muestra una ventana en la pantalla y pone el programa en modo de espera.
Tanto las ventanas como los widgets están definidos en la estructura del widget: no hice estructuras separadas para cada objeto, porque No encontré una manera conveniente de implementar esto, dado que
Go no tiene herencia. Esta estructura incluye campos comunes a la mayoría de los widgets y una cadena de mapa [cadena], que contiene propiedades específicas de un objeto en particular:
type Widget struct { Parent *Widget Type string Name string X int [...] Font *Font AProps map[string]string aWidgets []*Widget }
Los métodos de esta estructura incluyen AddWidget (), así como SetText (), SetImage (), SetParam (), SetColor (), SetFont (), GetText (), Move (), Enable (), etc. Me gustaría mencionar SetCallBackProc () y SetCallBackFunc (), para configurar controladores de eventos.
Sería inapropiado enumerar todas las funciones, estructuras y métodos aquí, para esto hay, más precisamente. Debe haber documentación. Solo diré algunas para dar una idea general:
Menu (), MenuContext (), EndMenu (), AddMenuItem (), AddMenuSeparator () - un conjunto de funciones para crear un menú, principal o contexto.
EvalProc (cadena sCode), EvalFunc (cadena sCode) pasan un fragmento de código Harbor (puede ser de varias líneas) para su ejecución en GuiServer, un tipo de implementación del lenguaje de script incorporado.
OpenForm (cadena sPath): crea una ventana basada en la descripción del archivo xml creado por HwGui Designer.
OpenReport (cadena sPath): imprime un informe basado en la descripción del archivo xml creado por HwGui Designer.
MsgInfo (), ..., SelectFile (), SelectColor (), SelectFont (): llama a cuadros de diálogo y cuadros de diálogo estándar.
InitPrinter () y un conjunto de métodos de estructura de la impresora: Say (), Box (), Line (), etc. proporcionan impresión a la impresora con la capacidad de previsualizar.
Aquí está la lista completa de widgets actualmente admitidos:
etiqueta, edición, botón, verificación, radio, radiogr, grupo, combo, mapa de bits, línea, panel (diseñado para alojar otros widgets), paneltop, panelbot, ownbtn (botón dibujado por el propietario), divisor, arriba hacia abajo, árbol, progreso, pestaña, navegar (tabla, como muchos lo llaman), cedit (editar con funciones avanzadas), mescal.
Todos ellos se enumeran en la función init () de extwidg.go junto con propiedades adicionales. accesible para cada uno de ellos: estas propiedades se establecen a través de Widget.AProps. Muchos de estos widgets tienen otras propiedades, especialmente navegar rico en ellos; se pueden configurar por separado utilizando el método SetParam ().
El volumen
externo resultó ser pequeño, está escrito en
Go puro, no extrae otros paquetes, excepto algunos estándar.
Multiplataforma es proporcionada por
GuiServer , que se puede compilar en Windows, Linux / Unix, Mac OS. Un cierto inconveniente está asociado precisamente con la necesidad de usar este módulo externo, que debe compilar desde las fuentes o descargar el terminado de mi sitio y colocarlo en el directorio especificado en PATH. Por cierto, es pequeño, solo alrededor de un mega y medio megabytes para Windows y aproximadamente tres, para Linux.
Cómo se ve, te mostraré un ejemplo de una pequeña aplicación
ETutor : el tutorial de Golang. Este programa presenta una colección de fragmentos de código en Go en forma de árbol. El código se puede editar, ejecutar para su ejecución. Nada especial, pero bastante cómodo. La colección se puede reponer, agregar nuevas colecciones. Ahora se recopilan (aún no completamente) un Tour de Go, Go by Example y varios ejemplos en el propio
External .
ETutor también se puede utilizar para, por ejemplo, organizar un conjunto de utilidades en Go. Entonces, capturas de pantalla.
Windows 10

Debian, Gnomo:

Y finalmente, los enlaces:
Externo en GithubGuiServer en GithubETutor en GithubUna página sobre GuiServer en mi sitio web donde puede descargar binarios ya preparadoshttps://groups.google.com/d/forum/guiserver : un grupo para debatir todos los problemas relacionados con GuiServer y externos
Artículo sobre GuiServer sobre Habré