GUI Golang: GTK + 3

Decidi escrever um aplicativo de desktop multiplataforma no Go . Feito uma versão CLI , tudo funciona bem. Sim, e a compilação cruzada no Go é suportada. Está tudo bem em geral. Mas também era necessária uma versão da GUI . E então começou ...


Golang gotk3


A escolha da biblioteca (ligação) para a GUI


O aplicativo deveria ser multiplataforma.
Portanto, ele deve compilar no Windows , GNU / Linux e macOS .
A escolha recaiu sobre essas bibliotecas:



Joguei de volta o Electron e outras estruturas que arrastam o Chromium e o node.js , porque eles pesam bastante e também consomem muitos recursos do sistema operacional.


Agora um pouco sobre cada biblioteca.


gotk3


Ligação à biblioteca GTK + 3 . A cobertura está longe de todas as possibilidades, mas todos os elementos essenciais estão presentes.


O aplicativo é compilado usando a go build padrão go build . A compilação entre plataformas é possível, com exceção do macOS . Somente com o macOS ele pode ser compilado para este sistema operacional, bem, com o macOS também pode ser compilado para Windows + GNU / Linux .


A interface parecerá nativa para GNU / Linux , Windows (você precisará especificar um tópico especial). Para o macOS, ele não parecerá nativo. Você só pode sair, a menos que seja um tópico terrível que emule os elementos nativos do macOS .


therecipe / qt


Biblioteca de ligação Qt 5 . Suporte para QML, widgets padrão. Em geral, muitas pessoas aconselham essa ligação.


qtdeploy usando o comando especial qtdeploy . Além das plataformas de desktop, também existem plataformas móveis. A compilação cruzada é feita usando o Docker . Para sistemas operacionais, a Apple pode ser compilada apenas com o macOS .


Se desejado, no Qt, você pode fazer com que a interface pareça nativa no sistema operacional da área de trabalho.


zserge / webview


A biblioteca, que foi originalmente escrita em C , o autor a ferrou em vários idiomas, incluindo Go . A visualização da web nativa é usada para exibir: Windows - MSHTML , GNU / Linux - gtk-webkit2 , macOS - Cocoa / WebKit . Além do código no Go, você também precisará escrever em JS , e o HTML será útil.


É compilado com go build , compilação cruzada é possível com o xgo .


Pode parecer nativo, tanto quanto um navegador padrão permite.


A escolha


Por que eu escolhi o gotk3 ?


Na pasta / qt, eu não gostava do sistema muito complicado para criar o aplicativo, eles até fizeram um comando especial.


O zserge / webview parece não ser ruim, não pesa muito, mas ainda é um webview e pode haver problemas padrão em tais aplicativos: talvez um lugar para onde ir. E este não é o Electron , onde o Chromium avançado está sempre incluído, mas em alguns Windows antigos tudo pode acontecer. Além disso, você também precisa escrever em JS .


Eu escolhi o gotk3 como algo médio. Você pode construí-lo com o padrão go build , parece aceitável e, de fato, eu amo o GTK + 3 !


Em geral, pensei que tudo seria simples. E o que em vão do Go eles dizem que tem um problema com a GUI . Mas como eu estava errado ...


Introdução


Instale tudo de gotk3 ( gtk , gdk , glib , cairo ) a nós mesmos:


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

Além disso, a própria biblioteca GTK + 3 deve estar instalada no seu sistema para desenvolvimento.


GNU / Linux


No Ubuntu :


 sudo apt-get install libgtk-3-dev 

No Arch Linux :


 sudo pacman -S gtk3 

macOS


Via Homebrew :


  brew install gtk-mac-integration gtk+3 

Windows


Não é tão simples aqui. As instruções oficiais sugerem o uso do MSYS2 e já fazem tudo nele. Pessoalmente, escrevi código em outros sistemas operacionais e fiz uma compilação cruzada para Windows no Arch Linux , que espero escrever em breve.


Exemplo simples


Agora, escrevemos um pequeno arquivo com o 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() } 

Você pode compilar usando o go build e, em seguida, execute o binário. Mas nós apenas rodamos:


 go run main.go 

Após o início, obtemos uma janela desse tipo:


Um exemplo simples de Golang gotk3


Parabéns! Você recebeu um aplicativo simples do README gotk3 !


Mais exemplos podem ser encontrados no Github gotk3 . Eu não vou desmontá-los. Vamos fazer algo que não está nos exemplos!


Glade


Existe uma coisa dessas para o Gtk + 3 - Glade . Este é um designer gráfico para o GTK + . Parece algo como isto:


Glade


Para não criar manualmente cada elemento e não colocá-lo posteriormente em algum lugar da janela usando o código do programa, você pode lançar o design inteiro no Glade . Salve tudo em um arquivo * .glade semelhante a XML e carregue-o através do nosso aplicativo.


Instalar Glade


GNU / Linux


Nas distribuições GNU / Linux, a instalação do glade é fácil. Em alguns Ubuntu, será:


 sudo apt-get install glade 

No Arch Linux :


 sudo pacman -S glade 

macOS


Os downloads do site oficial são muito antigos. Portanto, é melhor instalar através do Homebrew :


 brew install glade 

E então execute:


 glade 

Windows


Você pode baixar a versão mais recente aqui . Pessoalmente, não o instalei no Windows , portanto não conheço a estabilidade do Glade lá.


Aplicação simples usando Glade


Em geral, eu projetei algo como esta janela:


Glade


Salvei e recebi o arquivo 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> 

Ou seja, temos a janela window_main ( GtkWindow ), na qual, dentro do contêiner ( GtkBox ), que contém o campo de entrada entry_1 ( GtkEntry ), o button_1 ( GtkButton ) e o label_1 ( GtkLabel ). Além disso, também existem atributos de bugs (configurei um pouco), visibilidade e outros atributos que a Glade adicionou automaticamente.


Vamos agora tentar carregar esta visualização em nosso 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() } 

Execute novamente:


 go run main.go 

E temos:


Golang glade gotk3


Viva! Agora mantemos o envio do formulário em um arquivo main.glade XML , e o código em main.go !


Signals


A janela inicia, mas vamos adicionar interatividade. Deixe o texto do campo de entrada quando você clicar no botão entrar no rótulo.


Para fazer isso, primeiro obtemos os elementos do campo de entrada, botão e rótulo no 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) 

Eu não manuseio os erros que a GetObject() retorna para tornar o código mais simples. Mas em um aplicativo de trabalho real, eles devem ser processados.


Bom Usando o código acima, obtemos nossos elementos de formulário. Agora vamos lidar com o sinal do botão clicked (quando o botão é pressionado). O sinal GTK + é essencialmente uma reação ao evento. Adicione o código:


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

Agora execute o código:


 go run main.go 

Depois de inserir algum texto no campo e clicar no botão Ir , veremos este texto no rótulo:


Golang Glade gotk3 sinal


Agora temos uma aplicação interativa!


Conclusão


Nesta fase, tudo parece simples e não difícil. Mas tive dificuldades com a compilação cruzada (porque o gotk3 é compilado com o CGO ), a integração com os sistemas operacionais e com a caixa de diálogo de seleção de arquivos. Eu até adicionei uma caixa de diálogo nativa ao projeto gotk . Além disso, meu projeto precisava de internacionalização. Existem também alguns recursos. Se você está interessado em ver tudo isso agora no código, pode dar uma olhada aqui .


Os códigos-fonte para exemplos do artigo estão aqui .


E se você quiser ler a sequência, poderá votar. E caso isso seja interessante para alguém, continuarei escrevendo.

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


All Articles