Golang GUI: GTK + 3

Decid铆 escribir una aplicaci贸n de escritorio multiplataforma en Go . Hecho una versi贸n CLI , todo funciona bien. S铆, y se admite la compilaci贸n cruzada en Go . Todo est谩 bien en general. Pero tambi茅n se necesitaba una versi贸n GUI . Y entonces comenz贸 ...


Golang gotk3


La elecci贸n de la biblioteca (enlace) para la GUI


Se supon铆a que la aplicaci贸n era multiplataforma.
Por lo tanto, debe compilarse bajo Windows , GNU / Linux y macOS .
La elecci贸n recay贸 en tales bibliotecas:



Devolv铆 Electron y otros frameworks que arrastran a Chromium y node.js con ellos, porque pesan bastante y tambi茅n consumen muchos recursos del sistema operativo.


Ahora un poco sobre cada biblioteca.


gotk3


Biblioteca GTK + 3 vinculante . La cobertura est谩 lejos de todas las posibilidades, pero todos los elementos esenciales est谩n presentes.


La aplicaci贸n se compila utilizando la go build est谩ndar go build . La compilaci贸n multiplataforma es posible, con la excepci贸n de macOS . Solo con macOS se puede compilar para este sistema operativo, bueno, con macOS tambi茅n se puede compilar para Windows + GNU / Linux .


La interfaz se ver谩 nativa de GNU / Linux , Windows (deber谩 especificar un tema especial). Para macOS no se ver谩 nativo. Solo puede salir a menos que sea un tema terrible que emular谩 los elementos nativos de macOS .


receta / qt


Biblioteca de enlace Qt 5 . Soporte para QML, widgets est谩ndar. En general, muchas personas aconsejan este enlace.


qtdeploy usando el qtdeploy especial qtdeploy . Adem谩s de las plataformas de escritorio, tambi茅n hay plataformas m贸viles. La compilaci贸n cruzada se realiza con Docker . Para los sistemas operativos, Apple solo se puede compilar con macOS .


Si lo desea, en Qt, puede hacer que la interfaz parezca nativa en el sistema operativo de escritorio.


zserge / webview


La biblioteca, que originalmente estaba escrita en C , el autor la atornill贸 a muchos idiomas, incluido Go . La vista web nativa se usa para mostrar: Windows - MSHTML , GNU / Linux - gtk-webkit2 , macOS - Cocoa / WebKit . Adem谩s del c贸digo en Go, tambi茅n necesitar谩 escribir en JS , y HTML ser谩 煤til.


Se compila con go build , la compilaci贸n cruzada es posible con xgo .


Puede parecer nativo tanto como lo permite un navegador est谩ndar.


La eleccion


驴Por qu茅 eleg铆 gotk3 ?


En therecipe / qt, no me gust贸 el sistema demasiado complicado para compilar la aplicaci贸n, incluso hicieron un comando especial.


zserge / webview parece no estar mal, no pesar谩 mucho, pero a煤n as铆 es webview y puede haber problemas est谩ndar que existen en tales aplicaciones: tal vez un lugar para ir a alg煤n lado. Y esto no es Electron , donde siempre se incluye el Chromium avanzado, pero en algunos Windows antiguos todo puede funcionar. Y adem谩s, tambi茅n tienes que escribir en JS .


Eleg铆 gotk3 como algo promedio. Puedes compilarlo con el est谩ndar go build , parece aceptable, 隆y de hecho me encanta GTK + 3 !


En general, pens茅 que todo ser铆a simple. Y en vano sobre Go , dicen que tiene un problema con la GUI . Pero qu茅 equivocado estaba ...


Empezando


Instale todo, desde gotk3 ( gtk , gdk , glib , cairo ) a nosotros mismos:


 go get github.com/gotk3/gotk3/... 

Adem谩s, la biblioteca GTK + 3 en s铆 misma debe estar instalada en su sistema para el desarrollo.


GNU / Linux


En Ubuntu :


 sudo apt-get install libgtk-3-dev 

En Arch Linux :


 sudo pacman -S gtk3 

macOS


V铆a Homebrew :


  brew install gtk-mac-integration gtk+3 

Ventanas


No es tan simple aqu铆. Las instrucciones oficiales sugieren usar MSYS2 y hacer todo lo que ya est谩 en 茅l. Personalmente, escrib铆 c贸digo en otros sistemas operativos e hice una compilaci贸n cruzada para Windows en Arch Linux , que espero escriba pronto.


Ejemplo simple


Ahora escribimos un peque帽o archivo con el c贸digo main.go :


 package main import ( "log" "github.com/gotk3/gotk3/gtk" ) func main() { //  GTK. gtk.Init(nil) //    ,   //     "destroy"     //     win, err := gtk.WindowNew(gtk.WINDOW_TOPLEVEL) if err != nil { log.Fatal("   :", err) } win.SetTitle(" ") win.Connect("destroy", func() { gtk.MainQuit() }) //         l, err := gtk.LabelNew(", gotk3!") if err != nil { log.Fatal("   :", err) } //     win.Add(l) //      win.SetDefaultSize(800, 600) //      win.ShowAll() //    GTK ( ).    //  gtk.MainQuit() gtk.Main() } 

Puede compilar usando el go build y luego ejecutar el binario. Pero solo lo ejecutamos:


 go run main.go 

Despu茅s de comenzar, obtenemos una ventana de este tipo:


Un ejemplo simple en Golang gotk3


Felicidades 隆Tienes una aplicaci贸n simple de README gotk3 !


Se pueden encontrar m谩s ejemplos en Github gotk3 . No los desmontar茅. 隆Mejor hagamos algo que no est谩 en los ejemplos!


Claro


Hay tal cosa para Gtk + 3 - Glade . Este es un dise帽ador gr谩fico para GTK + . Se parece a esto:


Claro


Para no crear manualmente cada elemento y no colocarlo m谩s tarde en alg煤n lugar de la ventana usando el c贸digo del programa, puede lanzar todo el dise帽o en Glade . Luego guarde todo en un archivo * .glade similar a XML y c谩rguelo a trav茅s de nuestra aplicaci贸n.


Instalar Glade


GNU / Linux


En distribuciones GNU / Linux, instalar glade es f谩cil. En algunos Ubuntu, ser谩:


 sudo apt-get install glade 

En Arch Linux :


 sudo pacman -S glade 

macOS


Las descargas del sitio oficial son muy antiguas. Por lo tanto, es mejor instalar a trav茅s de Homebrew :


 brew install glade 

Y luego corre:


 glade 

Ventanas


Puede descargar la 煤ltima versi贸n aqu铆 . Personalmente no lo instal茅 en Windows en absoluto, por lo que no s茅 sobre la estabilidad de Glade all铆.


Aplicaci贸n simple usando Glade


En general, dise帽茅 algo como esta ventana:


Claro


Guardado y recibido el archivo main.glade :


 <?xml version="1.0" encoding="UTF-8"?> <!-- Generated with glade 3.22.1 --> <interface> <requires lib="gtk+" version="3.20"/> <object class="GtkWindow" id="window_main"> <property name="title" translatable="yes"> Glade</property> <property name="can_focus">False</property> <child> <placeholder/> </child> <child> <object class="GtkBox"> <property name="visible">True</property> <property name="can_focus">False</property> <property name="margin_left">10</property> <property name="margin_right">10</property> <property name="margin_top">10</property> <property name="margin_bottom">10</property> <property name="orientation">vertical</property> <property name="spacing">10</property> <child> <object class="GtkEntry" id="entry_1"> <property name="visible">True</property> <property name="can_focus">True</property> </object> <packing> <property name="expand">False</property> <property name="fill">True</property> <property name="position">0</property> </packing> </child> <child> <object class="GtkButton" id="button_1"> <property name="label" translatable="yes">Go</property> <property name="visible">True</property> <property name="can_focus">True</property> <property name="receives_default">True</property> </object> <packing> <property name="expand">False</property> <property name="fill">True</property> <property name="position">1</property> </packing> </child> <child> <object class="GtkLabel" id="label_1"> <property name="visible">True</property> <property name="can_focus">False</property> <property name="label" translatable="yes">This is label</property> </object> <packing> <property name="expand">False</property> <property name="fill">True</property> <property name="position">2</property> </packing> </child> </object> </child> </object> </interface> 

Es decir, tenemos la ventana window_main ( GtkWindow ), en la que dentro del contenedor ( GtkBox ), que contiene el campo de entrada entry_1 ( GtkEntry ), button_1 ( GtkButton ) y label_1 ( GtkLabel ). Adem谩s, tambi茅n hay atributos de errores (configur茅 un poco), visibilidad y otros atributos que Glade agreg贸 autom谩ticamente.


Ahora intentemos cargar esta vista en nuestro main.go :


 package main import ( "log" "github.com/gotk3/gotk3/gtk" ) func main() { //  GTK. gtk.Init(nil) //   b, err := gtk.BuilderNew() if err != nil { log.Fatal(":", err) } //       Glade err = b.AddFromFile("main.glade") if err != nil { log.Fatal(":", err) } //      ID obj, err := b.GetObject("window_main") if err != nil { log.Fatal(":", err) } //       gtk.Window //     "destroy"     //     win := obj.(*gtk.Window) win.Connect("destroy", func() { gtk.MainQuit() }) //      win.ShowAll() //    GTK ( ).    //  gtk.MainQuit() gtk.Main() } 

Corre de nuevo:


 go run main.go 

Y obtenemos:


Golang glade gotk3


隆Hurra! Ahora guardamos el env铆o del formulario en un archivo main.glade XML , y el c贸digo en main.go !


Se帽ales


La ventana se inicia, pero agreguemos interactividad. Deje que el texto del campo de entrada cuando haga clic en el bot贸n entre en la etiqueta.


Para hacer esto, primero obtenemos los elementos del campo de entrada, bot贸n y etiqueta en el c贸digo:


 //    obj, _ = b.GetObject("entry_1") entry1 := obj.(*gtk.Entry) //   obj, _ = b.GetObject("button_1") button1 := obj.(*gtk.Button) //   obj, _ = b.GetObject("label_1") label1 := obj.(*gtk.Label) 

No manejo los errores que devuelve la funci贸n GetObject() para simplificar el c贸digo. Pero en una aplicaci贸n real de trabajo, deben ser procesados.


Bueno Usando el c贸digo anterior, obtenemos nuestros elementos de formulario. Ahora manejemos la se帽al del bot贸n presionado (cuando se presiona el bot贸n). La se帽al GTK + es esencialmente una reacci贸n al evento. Agrega el c贸digo:


 //      button1.Connect("clicked", func() { text, err := entry1.GetText() if err == nil { //       label1.SetText(text) } }) 

Ahora ejecuta el c贸digo:


 go run main.go 

Despu茅s de ingresar un texto en el campo y hacer clic en el bot贸n Ir , veremos este texto en la etiqueta:


Golang Glade gotk3 se帽al


Ahora tenemos una aplicaci贸n interactiva!


Conclusi贸n


En esta etapa, todo parece simple y no dif铆cil. Pero tuve dificultades con la compilaci贸n cruzada (porque gotk3 se compila con CGO ), la integraci贸n con los sistemas operativos y con el di谩logo de selecci贸n de archivos. Incluso agregu茅 un di谩logo nativo al proyecto gotk . Adem谩s, mi proyecto necesitaba internacionalizaci贸n. Tambi茅n hay algunas caracter铆sticas. Si est谩 interesado en ver todo esto ahora en el c贸digo, puede echar un vistazo aqu铆 .


Los c贸digos fuente para ejemplos del art铆culo est谩n aqu铆 .


Y si quieres leer la secuela, puedes votar. Y en caso de que resulte interesante para alguien, continuar茅 escribiendo.

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


All Articles