Главная » Хабрахабр » External — GUI для Golang

External — GUI для Golang

Приветствую вас, коллеги!

Здесь я хочу представить конкретную реализацию этой идеи — новый GUI-фреймворк для GolangExternal. Около месяца назад я опубликовал здесь статью GUI-фреймворки — на поток, где предлагалась технология создания GUI-фреймворков для разных языков программирования, основанная на подключении (tcp/ip или каком другом) к внешнему процессу, играющему роль своеобразного GUI-сервера.

В первую очередь, потому, что ни один из них не устраивал меня в полной мере. Зачем вообще потребовалось писать новый GUI для Golang, если в наличии уже имеется немало таких инструментов? По-возможности, не очень громоздкое, имеющее минимум зависимостей — я привержен минималистическому подходу. Нужно было что-то для создания десктопных приложений, кросс-платформенное, чтобы выглядело естественно для каждой платформы.

Две позиции — app и walk были сразу вычеркнуты, как не соответствующие требованию кросс-платформенности. Я ориентировался вот на этот список. Во-первых, мне кажется несколько непривычным строить десктопное приложение как веб-страницу и, во-вторых, они тянут за собой довольно тяжелые движки. После некоторого раздумья отверг и те, что основаны на html/css/javascript. Представляете, сколько всего должно быть установлено у конечного пользователя, чтобы запустить даже небольшую утилиту? Так, например, go-astilectron и gowd основаны на Electron и nw.js, соответственно, а эти, в свою очередь, на node.js. Разве что go-sctiter с этой точки зрения выглядит предпочтительнее: стоящий за ним Sciter не столь монстрообразен.

Это, судя по всему, основательно сделанные пакеты, но я отказался и от них, потому что, на мой взгляд, использовать GTK под Windows — не лучшее решение. Go-gtk и gotk3 основаны на GTK. Qt binding — мощная штука, конечно, но достаточно сложная, и размеры… Когда я прочитал: «You also need 2. GTK-окна не выглядят под Windows «нативными». Сам Go занимает в десять раз меньше места. 5 GB free RAM (which only needed during initial setup) and at least 5 GB free disk space», последние сомнения отпали. А тут еще и лицензионные ограничения: «this binding with its LGPL license is not suitable to be used in closed source application that are intended to be distributed to the general public».

Ui мог бы быть неплохим вариантом, но он еще на mid-alpha стадии. Что у нас осталось из списка? Несколько смутило, что, с одной стороны, «Fyne is built entirely using vector graphics», а, с другой, «EFL windows packages are currently much older so you will not see the vector graphics portions of Fyne applications» — вот так. Fyne тоже выглядит неплохо, но, похоже, не вполне готов. Ну и не нравится, что для того, чтобы под Windows установить EFL (графическая библиотека, на которой основан Fyne), нужен MSYS.

Короче, при всем уважении к авторам перечисленных пакетов и к продуктам их труда, для себя я ничего не выбрал и с чистой совестью приступил к тому, что и хотел делать — написать новый GUI фреймворк — External.

External запускает его, присоединяется к нему по tcp/ip, посылает команды/запросы на создание окон и виджетов, манипулирование ими и пр. Как я уже писал в предыдущей статье, External не реализует GUI-элементы самостоятельно, он использует для этого отдельное приложение, отдельный процесс, выступающий в роли GUI-сервера, это приложение так и называется — GuiServer. и принимает от него сообщения.

Вот простейшая программа, создающая окно с традиционной надписью Hello, world:

package main import egui "github.com/alkresin/external" func main() 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()
}

Функция Init() запускает GuiServer и присоединяется к нему. Ей может быть передан строковый параметр, определяющий, если надо, название GuiServer'а и путь к нему, ip адрес и порт, уровень журналирования.

Метод AddWidget() — добавляет виджет типа label. InitMainWindow() создает главное окно приложения с заданными параметрами.

не нашел удобного способа это реализовать, учитывая, что в Go нет наследования. Activate() — выводит окно на экран и переводит программу в режим ожидания.
И окна, и виджеты определяются в структуре Widget — я не стал делать отдельные структуры для каждого объекта, т.к. В эту структуру входят поля, общие для большинства виджетов, и map[string]string, где собраны свойства, характерные для конкретного объекта:

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

В число методов этой структуры входят уже знакомый нам AddWidget(), а также SetText(), SetImage(), SetParam(), SetColor(), SetFont(), GetText(), Move(), Enable() и др. Особо хотел бы отметить SetCallBackProc() и SetCallBackFunc() — для установки обработчиков событий.
Перечислять здесь все функции, структуры и методы было бы неуместным, для этого есть, точнее. должна быть, документация. Скажу только о некоторых, чтобы дать какое-то общее представление:

обеспечивают печать на принтер с возможностью предпросмотра. Menu(), MenuContext(), EndMenu(), AddMenuItem(), AddMenuSeparator() — набор функций для создания меню, главного или контекстного.
EvalProc(sCode string), EvalFunc(sCode string) передают фрагмент Harbour кода (можно многострочный) для исполнения на GuiServer — своего рода реализация встроенного скриптового языка.
OpenForm(sPath string) — создает окно на основе описания из xml-файла, созданного HwGui Designer'ом.
OpenReport(sPath string) — печатает отчет на основе описания из xml-файла, созданного HwGui Designer'ом.
MsgInfo(), ..., SelectFile(), SelectColor(), SelectFont() — вызов стандартных messagebox'ов и диалогов.
InitPrinter() и набор методов структуры Printer: Say(), Box(), Line() и др.

Вот полный список поддерживаемых в настоящее время виджетов:
label, edit, button, check, radio, radiogr, group, combo, bitmap, line, panel (предназначен для размещения на нем др.виджетов), paneltop, panelbot, ownbtn (ownerdrawn кнопка), splitter, updown, tree, progress, tab, browse (таблица, как его многие называют), cedit (edit с расширенными возможностями), monthcal.

доступными для каждого из них — именно эти свойства устанавливаются через Widget. Все они перечислены в функции init() extwidg.go вместе с дополнительными свойствами. У многих из перечисленных виджетов есть и другие свойства, особенно богат на них browse; их можно задать отдельно, используя метод SetParam(). AProps.

Кросс-платформенность обеспечивается GuiServer'ом, который можно скомпилировать под Windows, Linux/Unix, Mac OS. External получился небольшим по объему, он написан на чистом Go, не тянет за собой других пакетов, кроме нескольких стандартных. Он, кстати, невелик — всего около полутора мегабайт для Windows и около трех — для Linux. Определенное неудобство связано именно с необходимостью использования этого внешнего модуля, который вам надо или собрать из исходников, или скачать готовый с моего сайта и поместить в каталог, указанный в PATH.

Эта программа представляет коллекцию фрагментов кода на Go в виде дерева. Как это выглядит, покажу на примере маленького приложения ETutor — Golang tutorial. Ничего особенного, но довольно удобно. Код можно редактировать, запускать на выполнение. Сейчас там собраны (еще не полностью) A Tour of Go, Go by Example и несколько примеров по самому External. Коллекцию можно пополнять, добавлять новые коллекции. Итак, скриншоты. ETutor можно использовать и для того, чтобы, например, упорядочить набор каких-либо утилит на Go.

Windows 10:

Debian, Gnome:

И, наконец, ссылки:

External на Github
GuiServer на Github
ETutor на Github
Страница о GuiServer у меня на сайте, откуда можно скачать готовые бинарники
https://groups.google.com/d/forum/guiserver — Группа для обсуждения всех вопросов, связанных с GuiServer и External
Статья о GuiServer на Хабре


Оставить комментарий

Ваш email нигде не будет показан
Обязательные для заполнения поля помечены *

*

x

Ещё Hi-Tech Интересное!

[Перевод] Интервью с Дэвидом Гобелем

Дэвид любезно согласился дать LEAF очень интересное интервью. Дэвид Гобель – изобретатель, филантроп, футурист и ярый сторонник технологий омоложения; вместе с Обри де Греем он известен как один из основателей Methuselah Foundation и как автор концепции Longevity Escape Velocity (LEV), ...

10 долларов на хостинг: 20 лет назад и сегодня

Всё кругом дорожает, а технологии дешевеют. Когда-то компьютер или мобильный телефон могли позволить себе единицы, сейчас эти устройства есть в каждой российской семье. Цена мегабайта за последние 20 лет упала в несколько тысяч раз. Ещё один пример — хостинг. В ...