Пользователь
121,5
рейтинг
19 марта 2015 в 13:37

Разработка → Нативная UI-библиотека для Go

Go*
Один из частых вопросов про Go — существует ли хорошая кроссплатформенная UI-библиотека на Go. Как правило, вопрошающих отсылали либо к go-qml, либо к andilabs/ui (биндинги к C-реализациям нативного UI для каждой платформы), но в целом достойного проекта по нативному Go UI пока не было. На днях же, пару разработчиков из Google открыли для open-source мира проект gxui, который нацелен восполнить нишу нативных UI-библиотек для Go.

Проект еще сырой, но выглядит неплохо и перспективно.

Давайте взглянем поближе.



Адрес проекта: github.com/google/gxui, и вот по-своему замечательное README:
Это экспериментальный код, и будет претерпевать существенные изменения. Свободно играйтесь с ним, пробуйте, но не расстраивайтесь, если API будет существенно переработан.

Пока что код недокументирован, и он точно не «идиоматический» Go. В ближайшие месяцы он будет сильно отрефакторен.

Это не официальный продукт Google, это просто код, которому случилось принадлежать Google.


Согласен, ридми не вдохновляющее, но давайте посмотрим, что на данный момент есть. Бегло изучив и испробовав примеры в директории samples/, попробовал написать банальное модальное окно.

package main

import (
	"fmt"

	"github.com/google/gxui"
	"github.com/google/gxui/drivers/gl"
	"github.com/google/gxui/themes/dark"
)

func appMain(driver gxui.Driver) {
	theme := dark.CreateTheme(driver)

	label := theme.CreateLabel()
	label.SetText("Are you sure?")

	yesButton := theme.CreateButton()
	yesButton.SetText("Yes")
	yesButton.OnClick(func(ev gxui.MouseEvent) {
		fmt.Println("Yes")
	})
	noButton := theme.CreateButton()
	noButton.SetText("No")
	noButton.OnClick(func(ev gxui.MouseEvent) {
		fmt.Println("No")
	})

	layout := theme.CreateLinearLayout()
	layout.AddChild(label)

	btnLayout := theme.CreateLinearLayout()
	btnLayout.AddChild(yesButton)
	btnLayout.AddChild(noButton)
	btnLayout.SetOrientation(gxui.Horizontal)

	layout.AddChild(btnLayout)
	layout.SetHorizontalAlignment(gxui.AlignCenter)
	layout.SetVerticalAlignment(gxui.AlignMiddle)

	window := theme.CreateWindow(120, 60, "Message Box")
	window.AddChild(layout)
	window.OnClose(driver.Terminate)

	gxui.EventLoop(driver)
}

func main() {
	gl.StartDriver("", appMain)
}



Похоже на GTK, и на Qt, правда? На мой взгляд, это хорошо — у кого есть опыт работы с GTK/Qt — будет проще понять логику работы с библиотекой, а когда речь пойдет об автогенераторах кода для UI, то тоже уже по протоптанной дороге можно будет идти (возможно даже, будет несложно адаптировать Glade или Qt Designer под эту библиотеку?).

Для взаимодействия с графической подсистемой пока используется только OpenGL, но дизайн библиотеки позволяет в будущем добавлять любой другой драйвер вывода, хоть AsciiArt, хоть DirectX.

Результат выглядит вот так:


Я не нашел пока, как сделать правильное выравнивание, resize виджетов или relayout при ресайзе окна (хотя функции для этого, вроде как есть). Со шрифтами пока тоже все на самом минимальном уровне.

Вот ещё немного примеров из исходников:

Анимированный прогрессбар.

Полигоны

Панели, которые можно ресайзить и переключать табы:

Списки


В целом, конечно, спрос на десктопные UI с каждым годом всё меньше и web-решения тут заняли прочную позицию. И хотя потребность в десктопных UI всё ещё есть, но вот этот тренд может убить энтузиазм и мотивацию авторов библиотеки. При этом, важно понимать, что сложность вообще самой задачи создания полнофункциональной UI библиотеки, еще и кросс-платформенной — огромна, и нуждается в колоссальных ресурсах, чтобы сделать это качественно и правильно. Учитывая всё это, я лично большие ожидания в этот проект не вкладывал бы, но поиграться будет интересно, особенно в тот момент, когда в README будет написано, что API is stable.
Впрочем, с другой стороны, проект уже собрал 1345 звезд на github-е, и судя по реакции в twitter/reddit, подобную библиотеку многие очень ждут.

Так что, кому интересно, пробуйте, контрибьютьте, следите за проектом.
divan0 @divan0
карма
128,0
рейтинг 121,5
Пользователь
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама

Самое читаемое Разработка

Комментарии (36)

  • 0
    да, отсутсвие нормальной UI для go — большой минус, к сожалению
    • –1
      Люди работают. Ожидайте.
  • +6
    web-решения заняли прочную позицию, потому что это единственный способ сделать красивый кроссплатформенный GUI на данный момент, не связываясь с Qt. Кроссплатформенные современные GUI-библиотеки нужны как воздух для всех языков. Стандартные виджеты не выглядят как говно разве только у OS X и Windows 8, всё остальное хочется перерисовать заново.

    Лично меня от перспективы делать GUI-приложения для всех платформ на HTML+CSS+JS охватывает уныние.

    Мне кажется, что современная GUI-библиотека должна удовлетворять следующим пунктам:
    1) Кроссплатформенность.
    2) Должна быть возможность написать приложение полностью на скриптовом языке. Для этого хорошо бы встроить, например, интерпретатор Lua.
    3) Это должен быть развитый язык общего назначения с широким набором библиотек. Т.е. я должен иметь возможность на этом скриптовом языке работать с файлами, и многое другое. JavaScript, при всей его мощи, до сих пор остаётся в плену браузерного окружения, что неимоверно раздражает в случае с Qt — я не хочу изучать ещё и C++, я хочу все возможности C++ в скриптовом языке.
    4) Богатый набор стандартных виджетов, возможность легко создавать собственные — произвольного внешнего вида и поведения.
    5) API должен быть лаконичным и простым, хорошо также иметь возможность описывать GUI декларативно (типа QML, Kivy language).
    6) Графический редактор интерфейса (как Qt Designer)
    7) Идентичный на всех платформах внешний вид.
    8) Библиотека должна использовать OpenGL там, где это оправдано. (по данным Google больше 90% всех устройств поддерживают OpenGL ES 2.0)
    9) Библиотека должна быть удобна в сборке и установке, иметь хорошую, регулярно обновляемую документацию. Она не должна быть избыточна (в той же Qt переписали почти все стандартные библиотеки C++).
    10) Небольшой размер. Простое приложение с GUI не должно весить под 100 МБ
    11) Небольшое число зависимостей, как можно более распространённых и без жёсткой привязки к конкретной версии.

    И что мы видим? Этим требованиям не удовлетворяет никто. Ближе всех подходят Qt и Kivy, имхо. Есть ещё Polycode, но он сырой и GUI там пока исключительно побочная фича.
    • 0
      потому что это единственный способ сделать красивый кроссплатформенный GUI на данный момент

      Не только поэтому.
      • появился мир смартфонов/планшетов и просто новый подход к вопросу — «я хочу пользоваться интерфейсом с любого из своих устройств»
      • как следствие, интерфейс должен работать и на мобильном телефоне и на экране телевизора
      • веб-приложениям не нужно заниматься обновлениями приложений конечному пользователю — а это для многих ситуаций громадный выигрыш, часто решающий
      • количество «виджетов» созданных для современных фронтендов будет покруче, чем у того же Qt. тут недавно была статья на хабре, как Highcharts.js прикручивали к Qt — подобной крутости charts-библиотек под десктопные UI нет и уже вряд ли будут
      • 0
        Хорошо. Я готов смириться с JavaScript.

        Вопросы: я могу с помощью JavaScript прочитать строку из файла?
        Я могу использовать Blink как интерпретатор (потому что мне не нужен браузер, мне нужно моё приложение на JS)? Чтобы пользователь запустил .exe файл и увидел окошко, внешний вид которого я полностью контролирую?
        • 0
          строку из файла можно прочитать реквестом, если файл json.
        • +1
          Для создания приложений есть отличнейшая штуковина node-webkit (ныне NW.js). Там скрешена нода и браузер. Файл вы без проблем прочитаете. И еще много всего сделаете. Позволяет как раз таки создавать exe-шники.
          • 0
            Размером больше сотни мегабайт…
            Один из принципов С++: «не платить за то, что не используешь»
            • 0
              Задачи разные. Если нужна производительность и экономия, берем C++. Если же нужно сделать быстро или знаешь только веб-технологии, то nw. Ну и кроссплатформенность, конечно.
            • +1
              Докладывали, что 30mb почти на дефолтных настройках.
        • +3
          Вопросы: я могу с помощью JavaScript прочитать строку из файла?
          Вы слышали про node.js?
      • 0
        Насчёт highcharts.js — pygal.org тоже очень неплох.

        А с подходом «уже ведь написали и оно так круто — поэтому не будем ничего трогать» — этак мы бы до сих пор на Коболе писали.
    • 0
      7) Идентичный на всех платформах внешний вид.
      Это зачем? Как написать, на все мобильных одинаковый внешний вид, тут и выдумывать не надо WEB UI. На платформах должен быть аутентичный вид
    • –1
      Хм, а FLTK не подойдет? (Не уверен разве что за качество/полноту language bindings и декларативные средства описания гуя.)
      1) Кроссплатформенность.
      Unix/Linux (X11), Windows, OS X.
      2) Должна быть возможность написать приложение полностью на скриптовом языке.
      3) Это должен быть развитый язык общего назначения с широким набором библиотек. Т.е. я должен иметь возможность на этом скриптовом языке работать с файлами, и многое другое.
      Вот здесь у них перечислены Tcl/Tk, Perl, Guile, Python, Ruby и др. Lua, правда, не упоминается.
      4) Богатый набор стандартных виджетов, возможность легко создавать собственные — произвольного внешнего вида и поведения.
      На мной вкус довольно богатый «из коробки», собственные создаются или наследуются легко и просто.
      5) API должен быть лаконичным и простым, хорошо также иметь возможность описывать GUI декларативно (типа QML, Kivy language).
      К API у меня нареканий нет; но декларативные средства (если не считать fluid) отсутствуют.
      6) Графический редактор интерфейса (как Qt Designer).
      FLUID, входит в поставку. Не такой продвинутый, как Qt Designer, конечно, но пользоваться можно.
      8) Библиотека должна использовать OpenGL там, где это оправдано. (по данным Google больше 90% всех устройств поддерживают OpenGL ES 2.0)
      Natively supports 3D graphics via OpenGL and its built-in GLUT emulation. Другое дело, что это все-таки скорее для кастомных виджетов.
      7) Идентичный на всех платформах внешний вид.
      9) Библиотека должна быть удобна в сборке и установке, иметь хорошую, регулярно обновляемую документацию. Она не должна быть избыточна (в той же Qt переписали почти все стандартные библиотеки C++).
      10) Небольшой размер. Простое приложение с GUI не должно весить под 100 МБ.
      11) Небольшое число зависимостей, как можно более распространённых и без жёсткой привязки к конкретной версии.
      Это все можно сказать про FLTK.
    • –1
      дубль
    • –1
      Не могу не вспомнить про Java+SWT. Компоненты нативные, кросплатформенно, один из самых мощных (и бесплатных) визуальных дизайнеров WindowBuilder для Eclipse. Минусы — не очень распостранненно (относительно), нужно тянуть примерно 20МБ на платформу (в прочем, JRE тоже весит немало).

      Или, если производительность некритична, писать UI под Chrome на HTML+CSS+JS и запускать это все дело через Chrome Application Mode — будет выглядеть не как страница браузера, а как нативное окно. (Чтобы такое сделать, нужно в хроме зайти в Menu — More tools — Create application shortcuts...).
  • 0
    Очень классно! Раньше, я считал, что лучше всего подход у wxWidgets — они используют нативные компоненты на каждой платформе, но теперь я за OpenGL подход, потомучто только так можно добиться настоящей кроссплатформенности.
    Ещё возникает вопрос, можно ли сделать реализацию QML на чистом Go?
    • 0
      Конечно, можно. Только зачем? Вам охота писать JS-вставки?
      • 0
        Можно что-нибудь придумать по этому поводу. Может прикрутить другой язык, тот же Lua, например. Идея в том, чтобы была опция декларативного создания интерфейсов, QML в качестве примера/основы хорошо подходит.
    • 0
      я тоже кстати думал об этом.
  • +1
    В качестве фантазий могу сказать так:
    прежде всего, разработка ПО ушла в схему: backend + frontend, и это очень сильно упростило разработку бэкенда, освободив его от рендеринга, оставив только логику, например фреймворк Grape для руби вообще API-only. А фронтенд стал развиваться как бешеный, не даром ходит шутка что если к любому английскому существительному добавить окончание JS — скорее всего такая библиотека (фреймворк, тулза, сборщик, линтер, и т.п.) уже есть. Всё это кстати породило бешеный спрос на фронтендеров.
    Далее тренды: компонентность, рективное программирование, отказ от массовых фреймворков в пользу библиотек и нативного кода (про это могу отдельно расссказать).
    Тренд в кроссплатформенности: всё идёт к тому, чтобы можно было на любой ОС запускать любые приложения под любые ОС. Я на Линуксе запускаю нативные андроид приложения (пусть пока через хром, но всё же), wine для windows. Скоро обещают совершить революцию и запускать нативные ObjC и Swift приложения под линукс. Под виндой я могу запускать нативные линуксовые утилиты, и даже иксы. Развитие технологий — вопрос времени.
    Тренд в UI — сейчас всё больше и больше уходят на html,css,js. Почему? Ведь даже телевизоры, микроволновки и духовые печи на кухне, холодильники — все имеют интерфейс, построенный на этом. А виной всему то, что мир ушёл в онлайн. Сейчас нет необходимости в приложении, которое будет работать нативно на ОС, т.к. для большинства задач уже подходят веб-приложения. Редакторы графики, текстовые, звуковые и видео редакторы — всё в онлайне. Хотите 3d игрушки? Нате, зависайте: webquake.quaddicted.com/Client/WebQuake.htm
    Хотите красоту и интерактивность ui — идите в HCJ. Здесь нет .net на 100500 мегабайт с кучей (реально кучей) ненужных зависимостей. Да, даже на линуксе «Hello world» на си занимает восемь килобайт, хотя текста там…
    #include <stdio.h>
    
    int main (void)
    {
    	printf ("Hello World\n");
    }
    

    Ок, резервирование памяти, стдио, это простительно. Но когда простите Hello World занимает 20+ мегабайт с .net компонентами — это уже слишком.

    А так, да, здорово что у Go есть UI, пусть и скромненький, зато свой. Это безусловно хороший шаг развития языка, который мне очень симпатичен. Тем не менее, я бы предпочёл его использовать как хороший сильный многопоточный (даже на уровне синтаксиса) бэкенд.
    • +1
      Что мне здесь не нравится — по умолчанию подразумевается знание как минимум 2-х языков — JS и того, на котором бэкенд. Т.е. либо у нас 2 человека, либо 1 человек, который пишет на 2-х языках (надо ещё посчитать HTML+CSS, которые развиваются очень быстро).

      JS работает нормально только в WebKit браузерах. Супероптимизированный Blink, которым занимается одна компания, и всё. Все остальные движки уже не тянут амбиции современных фронтендеров. Все эти asm.js, JIT-компиляторы и пр… Кажется, что из технологии выжимают последние соки. Уже вовсю начинают использовать WebGL.

      JS до сих пор узконаправленный — он работает только в браузере. А можно напрямую к JS прикрутить код на C/C++? Разве только в рамках Qt. Тот же Python уделывает JS по широте возможностей, а Lua по простоте встраивания его и в него. Я погуглил как в JS прочитать строку из файла и у меня волосы встали дыбом. А эта, совершенно рутинная операция, должна быть в скриптовом языке для GUI. Потому что я хочу на свойство виджета привязать лямбда-функцию, которая должна уметь делать всё, что я захочу, а не только то, что умеет браузер. Связываться с локальным кодом с помощью web-протоколов — извращение. Не говоря уже то том, что интерфейс этот однонаправленный — бэкенд не может вызвать фронтенд (разве только в Qt или Node.js)
      • 0
        Совершенно согласен с вами, тем не менее хочу обратить внимание на io.js, к вопросу о работе js исключительно в браузерах.

        Что же касается знания нескольких языков — я не понимаю проблемы совершенно. Язык — это инструмент. Когда мне было нужно писать изящный парсер на питоне — я написал изящный парсер на питоне. Java? Окей гугл, она не так сложна как может показаться. Go — без проблем, после прочтения первой же книги — пара полезных утилит для повседневной жизни в убунте. Вынашиваю идею ОРМ для Go, но это пока только в голове. Тем не менее — не вижу проблем. Если нужно в голове держать несколько языков — держите. Главное — всё равно логика.

        А так, да, согласен, есть еще белые пятна, с теми же коллбеками из бэкенда. Реализуемо, но сложно. Опять же, всё зависит от задачи. Да наверное вообще всё от задачи зависит. Есть вещи, которые вообще только на асме лучше всего делать )
      • 0
        Вы пытаетесь frontend JS представлять на месте традиционных системных языков. Но мы же тут о другом — «веб-решение» подразумевает другую модель взаимодействия с пользователем, и там где раньше вам нужно было «читать файл», сейчас вы «принимаете HTTP-запрос». Банальный пример — загрузка изображения. В случае нативной десктопной аппликации вам без умения читать файла с файловой системы не обойтись, в случае с веб-приложением — бекенду это не нужно, зато нужно уметь принимать изображение от клиента.

        А так на JS можно делать все, node.js вам в пример.
        • 0
          Для хорошо спроектированной GUI-библиотеки сделать все необходимые сетевые возможности вовсе не непосильная задача.
      • 0
        JS до сих пор узконаправленный — он работает только в браузере. А можно напрямую к JS прикрутить код на C/C++? Разве только в рамках Qt. Тот же Python уделывает JS по широте возможностей, а Lua по простоте встраивания его и в него.
        JS уже давно не только «браузерный»; есть легковесные, легко встраиваемые реализации (например, duktape), хотя Lua, конечно, встраивать проще (чтобы к duktape «прикрутить код на C/C++», нужно писать много boilerplate кода, который по-хорошему должен авто-генерироваться, по типу SWIG).

        Но у Lua, при всех ее достоинствах, очень плохая compatibility track record — никогда нельзя быть уверенным, что ничего не сломается при изменении даже минорной версии — у JS с этим намного лучше.
    • +1
      Боюсь, это ожидание скорого пришествия антихриста Internet of Things и всеобщего онлайна закончится также как всеобщее ожидание смерти PC и прихода устройств с тачскрином.
    • 0
      Но порог вхождения в современный веб гораздо выше, чем в Qt, например. А как, например, в веб интерфейсе отображать быстро меняющиеся динамические данные? Пример: я сейчас думаю сделать на Go генератор анимаций для моего самодельного светодиодного дисплея. Как мне в веб-интерфейсе сделать предварительный просмотр?
  • +1
    Знаете, я вот посмотрел в зависимости, там freetype-go. Который самописный, с нуля, не биндинг к системному рендереру. То есть, приложения на gxui вообще никогда не будут выглядеть нативно и хоть чуть-чуть пристойно.
    • 0
      А можно подробней? Я плохо понимаю, почему самописный рендерер не может быть в итоге пристойным.
      Сейчас, понятно, со шрифтами ноль полный там в плане пристойности, но если проект будут развивать, то тема шрифтов, полагаю, будет одной из главных в плане критики/пул-реквестов.
      • +1
        Ну, про пристойность это была по большей части шутка.
        А шрифты просто никогда не будут выглядеть одинаково с отрендеренными нативно, что очевидно плохо. В буквальном смысле очевидно.

        То есть, я, конечно, понимаю, автора freetype-go — писать свой truetype renderer интереснее, чем биндинги к системному. А вот тех, кто это использует не в игровом движке — нет.
  • +6
    А в чем он нативный?
    Нативный UI — это же, вроде, когда виджеты отрисовывает сама операционная система?

    Или нативный — в том смысле что написан полностью на GO?
    • –2
      Да, в том смысле, что написан полностью на Go, а не враппер над родными C/C++/etc. UI-библиотеками для каждой платформы.
      • +6
        Тогда это скорее pure. Как pure ruby gem например.
        • 0
          Согласен, pure ближе по смыслу.
  • +1
    В golang-nuts несколько дней назад автор отписывался, что он всего лишь на выходных накидал проект и не ожидал такой популярности.
    Там еще ничего не готово.

    Мои пять копеек насчет трендов: в итоге крупные компании с толстым маркетинговым бюджетом продавят то решение, которое будет им выгодно, причем по причинам нам неизвестным. Причины, по которым лично я не хочу проснуться в мире «JavaScript Everywhere» основываются на моем личном опыте и интервью с создателями языка, прочитанными в книге Coders at Work; это не мешает мне использовать данный язык для своих целей там, где он отлично подходит — в web-интерфейсах. С теми же JS-фреймворками для разработки игр у меня исключительно отрицательный опыт на протяжении нескольких лет.

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.