Externo - GUI para Golang

Saudações, colegas!

Há cerca de um mês, publiquei um artigo sobre estruturas de GUI aqui - em um thread que oferecia a tecnologia para criar estruturas de GUI para diferentes linguagens de programação, com base na conexão (tcp / ip ou alguma outra) a um processo externo que desempenha o papel de um tipo de servidor de GUI. Aqui, quero apresentar uma implementação concreta dessa idéia - uma nova estrutura da GUI para Golang - Externa .

Por que foi necessário escrever uma nova GUI para Golang , se já existem muitas dessas ferramentas disponíveis? Primeiro de tudo, porque nenhum deles me serviu ao máximo. Algo era necessário para criar aplicativos de desktop, multiplataforma, com aparência natural para cada plataforma. Se possível, não muito volumoso, com um mínimo de dependências - estou comprometido com uma abordagem minimalista.

Fui guiado por esta lista . Duas posições - app e walk foram imediatamente riscadas por não atenderem aos requisitos da plataforma cruzada. Depois de pensar um pouco, ele rejeitou aqueles baseados em html / css / javascript. Em primeiro lugar, parece-me um pouco incomum criar um aplicativo de desktop como uma página da Web e, em segundo lugar, eles usam motores bastante pesados. Assim, por exemplo, go-astilectron e gowd são baseados em Electron e nw.js , respectivamente, e estes, por sua vez, são baseados em node.js. Imagine quanto tudo deve ser instalado pelo usuário final para executar até um pequeno utilitário? A menos que o go-sctiter pareça preferível desse ponto de vista: o Sciter atrás dele não é tão monstruoso.

Go-gtk e gotk3 são baseados em GTK. Aparentemente, esses são pacotes completos, mas eu também os recusei, porque, na minha opinião, usar o GTK no Windows não é a melhor solução. As janelas GTK não parecem nativas no Windows. A ligação com o Qt é uma coisa poderosa, é claro, mas um pouco complicada, e as dimensões ... Quando eu li: "Você também precisa de 2,5 GB de RAM livre (que só era necessária durante a instalação inicial) e pelo menos 5 GB de espaço livre em disco", as últimas dúvidas desapareceram. O próprio Go ocupa dez vezes menos espaço. E há restrições de licenciamento: “essa ligação com sua licença LGPL não é adequada para ser usada em aplicativos de código fechado que se destinam a ser distribuídos ao público em geral”.

O que resta da lista? A interface do usuário pode ser uma boa opção, mas ainda está no estágio mid-alpha. Fyne também parece muito bom, mas não parece estar completamente pronto. Foi um pouco embaraçoso que, por um lado, “o Fyne seja construído inteiramente usando gráficos vetoriais” e, por outro lado, “os pacotes do Windows EFL atualmente sejam muito mais antigos, portanto você não verá as partes dos gráficos vetoriais dos aplicativos Fyne” - assim. Bem, não gosto disso para instalar o EFL (a biblioteca gráfica na qual Fyne se baseia) no Windows, você precisa do MSYS .

Em suma, com todo o respeito devido aos autores dessas embalagens e aos produtos de seu trabalho, eu não escolhi nada para mim e, com a consciência limpa, continuei com o que eu queria fazer - escreva uma nova estrutura de GUI - Externa .

Como escrevi em um artigo anterior, o External não implementa elementos da GUI por conta própria, ele usa um aplicativo separado para isso, um processo separado que atua como um servidor da GUI, esse aplicativo é chamado GuiServer . O externo o lança, junta-se via tcp / ip, envia comandos / solicitações para criar janelas e widgets, manipulá-los etc., e recebe mensagens dele.

Aqui está um programa simples que cria uma janela com a inscrição tradicional Olá, 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() } 

A função Init () inicia o GuiServer e junta-se a ele. Um parâmetro de string pode ser passado para ele, que determina, se necessário, o nome do GuiServer e seu caminho, endereço IP e porta e o nível de registro.

InitMainWindow () cria a janela principal do aplicativo com os parâmetros especificados. Método AddWidget () - Adiciona um widget do tipo label.

Ativar () - exibe uma janela na tela e coloca o programa no modo de espera.
As janelas e os widgets são definidos na estrutura do widget - não criei estruturas separadas para cada objeto, porque Não encontrei uma maneira conveniente de implementar isso, uma vez que o Go não tem herança. Essa estrutura inclui campos comuns à maioria dos widgets e mapear [string], que contém propriedades específicas para um objeto específico:

 type Widget struct { Parent *Widget Type string Name string X int [...] Font *Font AProps map[string]string aWidgets []*Widget } 

Os métodos dessa estrutura incluem os familiares AddWidget (), bem como SetText (), SetImage (), SetParam (), SetColor (), SetFont (), GetText (), Move (), Enable (), etc. Gostaria de mencionar SetCallBackProc () e SetCallBackFunc () - para definir manipuladores de eventos.
Seria inapropriado listar todas as funções, estruturas e métodos aqui, para isso existe, mais precisamente. deve haver documentação. Vou dizer apenas alguns para dar uma idéia geral:

Menu (), MenuContext (), EndMenu (), AddMenuItem (), AddMenuSeparator () - um conjunto de funções para criar um menu, principal ou contexto.
EvalProc (sCode string), EvalFunc (sCode string) transmitem um fragmento de código Harbor (pode ser multilinha) para execução no GuiServer - um tipo de implementação da linguagem de script interna.
OpenForm (sPath string) - cria uma janela com base na descrição do arquivo xml criado pelo HwGui Designer.
OpenReport (sPath string) - imprime um relatório com base na descrição do arquivo xml criado pelo HwGui Designer.
MsgInfo (), ..., SelectFile (), SelectColor (), SelectFont () - chama caixas de diálogo e caixas de mensagem padrão.
InitPrinter () e um conjunto de métodos de estrutura da impressora: Say (), Box (), Line () etc.) fornecem impressão à impressora com a capacidade de visualizar.

Aqui está a lista completa de widgets atualmente suportados:
etiqueta, edição, botão, verificação, rádio, radiogr, grupo, combinação, bitmap, linha, painel (projetado para hospedar outros widgets), paneltop, panelbot, ownbtn (botão ownerdrawn), divisor, atualização, árvore, progresso, guia, navegue (tabela, como muitos chamam), cedit (edite com recursos avançados), monthcal.

Todos eles estão listados na função init () do extwidg.go, além de propriedades adicionais. acessível para cada um deles - essas propriedades são definidas por meio do Widget.AProps. Muitos desses widgets têm outras propriedades, especialmente navegando ricamente neles; eles podem ser definidos separadamente usando o método SetParam ().

Externo acabou por ser pequeno em volume, está escrito em Go puro, não puxa outros pacotes, exceto alguns padrão. A plataforma cruzada é fornecida pelo GuiServer , que pode ser compilado no Windows, Linux / Unix, Mac OS. Um certo inconveniente está associado precisamente à necessidade de usar este módulo externo, que você precisa compilar a partir das fontes, ou baixar o final do meu site e colocá-lo no diretório especificado em PATH. Aliás, é pequeno - apenas cerca de um megabyte e meio para Windows e cerca de três - para Linux.

Como parece, mostrarei um exemplo de um pequeno aplicativo ETutor - o tutorial de Golang. Este programa apresenta uma coleção de fragmentos de código no Go na forma de uma árvore. O código pode ser editado, executado para execução. Nada de especial, mas bastante confortável. A coleção pode ser reabastecida, adicione novas coleções. Agora, são coletados (ainda não completamente) um Tour of Go, Go by Example e vários exemplos no próprio External . O ETutor também pode ser usado para, por exemplo, organizar um conjunto de utilitários no Go. Então, screenshots.

Windows 10:



Debian, Gnome:



E, finalmente, os links:

Externo no Github
GuiServer no Github
ETutor no Github
Uma página sobre o GuiServer no meu site, onde você pode baixar binários prontos
https://groups.google.com/d/forum/guiserver - Um grupo para discutir todos os problemas relacionados ao GuiServer e External
Artigo sobre GuiServer no Habré

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


All Articles