Содержание

GUI на Golang: GTK+ 3 / Хабр

Решил я написать одно кроссплатформенное десктопное приложение на Go. Сделал CLI-версию, всё работает отлично. Да ещё и кросскомпиляция в Go поддерживается. Всё в общем отлично. Но понадобилась также и GUI-версия. И тут началось…


Выбор библиотеки (биндинга) для GUI

Приложение должно было быть кроссплатформенным.
Поэтому должно компилироваться под Windows, GNU/Linux и macOS.
Выбор пал на такие библиотеки:


Electron и прочие фреймворки, которые тянут с собой Chromium и node.js, я откинул так как они весят достаточно много, ещё и съедают много ресурсов операционной системы.

Теперь немного о каждой библиотеке.


gotk3

Биндинг библиотеки GTK+ 3. Покрытие далеко не всех возможностей, но всё основное присутсвует.

Компилируется приложение с помощью стандартного

go build. Кроссплатформенная компиляция возможна, за исключением macOS. Только с macOS можно скомпилировать под эту ОС, ну и с macOS можно будет скомпилировать и под Windows + GNU/Linux.

Интерфейс будет выглядить нативно для GNU/Linux, Windows (нужно будет указать специальную тему). Для macOS будет выглядеть не нативно. Выкрутиться можно только разве что страшненькой темой, которая будет эмулирувать нативные элементы macOS.


therecipe/qt

Биндинг библиотеки Qt 5. Поддержка QML, стандартных виджетов. Вообще этот биндинг многие советуют.

Компилируется с помощью специальной команды qtdeploy. Кроме десктопных платформ есть также и мобильные. Кросскомпиляция происходит с помощью Docker. Под операционные системы

Apple можно скомпилировать только с macOS.

При желании на Qt можно добиться чтобы интерфейс выглядел нативно на десктопных ОС.


zserge/webview

Библиотека, которая написана изначально на C, автор прикрутил её ко многим языкам, в том числе и к Go. Использывается нативный webview для отображения: WindowsMSHTML, GNU/Linuxgtk-webkit2, macOSCocoa/WebKit. Кроме кода на Go нужно будет и на JS пописать, ну и HTML пригодится.

Компилируется при помощи go build, кросскомпиляция возможна с помощью xgo.

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


Выбор

Почему же я выбрал именно gotk3?

В therecipe/qt мне не понравилась слишком сложная система сборки приложения, даже специальную команду сделали.

zserge/webview вроде бы не плох, весить будет не много, но всё-таки это webview и могут быть стандартные проблемы, которые бывают в таких приложениях: может что-то где-то поехать. И это не Electron, где всегда в комплекте продвинутый Chromium, а в какой-нибудь старой Windows может всё поехать. Да и к тому же придётся ещё и на JS писать.

gotk3 я выбрал как что-то среднее. Можно собирать стандартным go build, выглядит приемлемо, да и вообще я

GTK+ 3 люблю!

В общем я думал, что всё будет просто. И что зря про Go говорят, что в нём проблема с GUI. Но как же я ошибался…


Начинаем

Устанавливаем всё из gotk3 (gtk, gdk, glib, cairo) себе:

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

Также у вас в системе должна быть установлена сама библиотека GTK+ 3 для разработки.


GNU/Linux

В Ubuntu:

sudo apt-get install libgtk-3-dev

В Arch Linux:

sudo pacman -S gtk3

macOS

Через Homebrew:

 brew install gtk-mac-integration gtk+3

Windows

Здесь всё не так просто.

В официальной инструкции предлагают использовать MSYS2 и уже в ней всё делать. Лично я писал код на других операционных системах, а кросскомпиляцию для Windows делал в Arch Linux, о чём надеюсь скоро напишу.


Простой пример

Теперь пишем небольшой файл с кодом 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() }

Спомпилировать можно с помощью команды go build, а потом запустить бинарник. Но мы просто запустим его:

go run main.go

После запуска получим окно такого вида:

Поздравляю! У вас получилось простое приложение из README

gotk3!

Больше примеров можно найти на Github gotk3. Их разбирать я не буду. Давайте лучше займёмся тем, чего нет в примерах!


Glade

Есть такая вещь для Gtk+ 3Glade. Это конструктор графических интерфейсов для GTK+. Выглядит примерно так:

Чтобы вручную не создавать каждый элемент и не помещать его потом где-то в окне с помощью программного кода, можно весь дизайн накидать в Glade. Потом сохранить всё в XML-подобный файл *.glade и загрузить его уже через наше приложение.


Установка Glade


GNU/Linux

В дистрибутивах GNU/Linux установить glade не составит труда. В какой-нибудь Ubuntu

это будет:

sudo apt-get install glade

В Arch Linux:

sudo pacman -S glade

macOS

В загрузках с официального сайта очень старая сборка. Поэтому устанавливать лучше через Homebrew:

brew install glade

А запускать потом:

glade

Windows

Скачать не самую последнюю версию можно здесь. Я лично на Windows вообще не устанавливал, поэтому не знаю насчёт стабильность работы там Glade.


Простое приложение с использованием Glade

В общем надизайнил я примерно такое окно:

Сохранил и получил файл main. glade

:

<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.1 -->
<interface>
  <requires lib="gtk+" version="3.20"/>
  <object>
    <property name="title" translatable="yes">Пример Glade</property>
    <property name="can_focus">False</property>
    <child>
      <placeholder/>
    </child>
    <child>
      <object>
        <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>
            <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>
            <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>
            <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>

То есть у нас получилось окно window_main (GtkWindow

), в котором внутри контейнер (GtkBox), который содержит поле ввода entry_1 (GtkEntry), кнопку button_1 (GtkButton) и метку label_1 (GtkLabel). Кроме этого ещё имеются аттрибуты отсупов (я настроил немного), видимость и другие аттрибуты, которые Glade добавила автоматически.

Давайте теперь попробуем загрузить это представление в нашем 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() }

Снова запускаем:

go run main.go

И получаем:

Ура! Теперь мы представление формы держим XML-подобном main.glade файле, а код в main.go!


Сигналы

Окно запускается, но давайте добавим интерактивности. Пусть текст из поля ввода при нажатии на кнопку попадёт в метку.

Для этого для начала получим элементы поля ввода, кнопки и метке в коде:

// Получаем поле ввода
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)

Я не обрабатываю ошибки, которые возвращает функция GetObject(), для того, чтобы код был более простым. Но в реальном рабочем приложении их обязательно необходимо обработать.

Хорошо. С помощью кода выше мы получаем наши элементы формы. А теперь давайте обработаем сигнал clicked кнопку (когда кнопка нажата). Сигнал GTK+ — это по сути реакция на событие. Добавим код:

// Сигнал по нажатию на кнопку
button1.Connect("clicked", func() {
    text, err := entry1.GetText()
    if err == nil {
        // Устанавливаем текст из поля ввода метке
        label1.SetText(text)
    }
})

Теперь запускаем код:

go run main.go

После ввода какого-нибудь текста в поле и нажатию по кнопке Go мы увидем этот текст в метке:

Теперь у нас интерактивное приложение!


Заключение

На данном этапе всё кажется простым и не вызывает трудностей. Но трудности у меня появились при кросскомпиляции (ведь gotk3 компилируется с CGO), интеграции с операционными системами и с диалогом выбора файла. Я даже добавил в проект gotk нативный диалог. Также в моём проекте нужна была интернационализация. Там тоже есть некоторые особенности. Если вам интересно увидеть это всё сейчас в коде, то можно подсмотреть здесь.

Исходые коды примеров из статьи находятся здесь.

А если хотите почитать продолжение, то можете проголосовать. И в случае, если окажется это кому-нибудь интересным, я продолжу писать.

Как я могу использовать Go для создания окна GUI?



Мне нужно сделать простое окно в Go для отображения некоторого текста, нет никакой необходимости в реальном интерфейсе типа GUI.

Как я могу сделать такое окно, используя Go?

go window
Поделиться Источник Vladimir verleg     30 сентября 2016 в 06:41

2 ответа




4

Симпатичный кросс-платформенный UI может быть создан с помощью HTML5/CSS/JS. Вы можете открыть собственное окно с полноэкранным браузерным движком (webview), в котором отображается ваш UI.

Есть крошечный фантик библиотеки для этого на Windows, MacOS и Linux — https://github.com/zserge/webview

Вы можете соединить ваши UI и основные части приложения с помощью Привязок Go-to-JS (библиотека webview предоставляет их) или websocket.

Поделиться zserge     24 октября 2017 в 17:59



3

walk — это наиболее распространенная библиотека, используемая для разработки basic GUI.

Вы можете импортировать пакет с помощью:

go получить github.com/lxn/walk

Я предполагаю, что вы работаете в windows OS, поэтому создайте exe и запустите его.

Более подробную информацию об этом можно получить из его источника.

Посетите https://github.com/lxn/walk

Поделиться shivendra pratap singh     30 сентября 2016 в 08:57


Похожие вопросы:


Какие библиотеки я могу использовать для создания GUI с Erlang?

Какие библиотеки я могу использовать для создания GUI для приложения Erlang? Пожалуйста, только один вариант для каждого ответа.


Как я могу использовать файл ресурсов (*. rc) для создания диалогового приложения

Как я могу использовать файл ресурсов (*. rc) для создания диалогового приложения? Я могу использовать CreateWindow или CreateWindowEx для создания главного окна приложения. И некоторые из…


Как использовать getframe() с объектом MATLAB GUIDE (GUI) для создания фильма?

Я хотел бы использовать getframe для захвата скриншота моего красивого объекта GUI, который я создал с помощью GUIDE . Я не могу просто использовать функциональность OS PrintScreen, потому что мне…


Какой инструмент (ы) GUI я могу использовать для создания файла сопоставления NHibernate из базы данных SQL?

Можете ли вы порекомендовать мне инструмент GUI или инструменты, которые я могу использовать для создания файла сопоставления NHibernate с соответствующим POCOS ? Спасибо!


Как использовать X window для создания интерфейса GUI для Linux OS?

Можете ли вы предоставить мне поверхностные знания об этом? Как я могу использовать последние версии linux kernel и X windows GUI для создания собственного встроенного интерфейса OS?


Могу ли я использовать `Win32::GUI` для создания значка в системном трее для моей программы командной строки Perl?

У меня есть скрипт Perl, который работает в бесконечном цикле. Я хотел бы иметь возможность свести это к минимуму в системном трее. Могу ли я использовать Win32::GUI для создания значка в системном…


Используя Go, как я должен получить доступ к компонентам окна в традиционных графических фреймворках на основе наследования?

Я провожу некоторые экспериментальные работы, используя привязки GTK для Go . Как и в большинстве фреймворков GUI, графическое приложение GTK обычно порождает главное окно, и работа приложения…


Как я могу использовать gtk.Builder.connect_signals только для подключения сигналов из одного окна?

Я разрабатываю приложение GUI с использованием Glade и Python 3. Я разработал UI в Glade; он состоит из главного окна приложения и пользовательского диалога с определенной информацией, которая…


Запуск Pygame без окна / GUI

Можно ли запустить pygame без создания окна pygame, поверхности или GUI? Я хочу использовать определенные функции pygame,но я не хочу, чтобы появлялся GUI. Например, эта функция не будет работать,…


Tkinter GUI кнопки становятся невидимыми после создания приложения с помощью Py2App

Я построил маленький GUI, используя Tkinter. GUI имеет, среди некоторых других элементов, три кнопки. Эти кнопки служат для открытия диалогового окна dystem и выбора определенных файлов данных и т….

Простое сетевое GUI приложение на Go + Fyne · Заметки разработчика

На днях меня попросили сделать простенький реестр записей, но так чтобы он был в виде GUI приложения и имел клиент-серверную архитектуру. Т. е. приложение должно состоять из двух частей:

  • сервер, который сохряняет данные в бд
  • клиент, который имеет формочку из нескольких полей после заполенения которых данные отправляются на сервер

Недавно я как раз прочитал про новый фреймворк Fyne для создания графичесих приложений на Go и решил опробыввать его на этой задаче.

Введение в Fyne

Fyne построен полностью с использованием векторной графики, что означает, что приложения, написанные с помощью Fyne, будут прекрасно масштабироваться до любого размера.

Приложения Fyne основаны на 1 слое (canvas) на окно. Каждый канвас имеет корневой CanvasObject, который может быть отдельным виджетом или контейнером для многих подобъектов, размер и положение которых контролируются макетом.

Каждый холст имеет свое происхождение вверху слева (0, 0), каждый элемент пользовательского интерфейса может масштабироваться в зависимости от устройства вывода, поэтому API не описывает пиксели или точные измерения.

Клиентская часть

Клиентская часть имеет форму с 3-мя полями и двумя кнопками. Выглядит она следующим образом:

Такую формочку можно создасть с помощью кода:

a := app.New()

w := a.NewWindow("Client")

planEvent := widget.NewEntry()
executor := widget.NewEntry()
count := widget.NewEntry()

form := widget.NewForm(
    widget.NewFormItem("План. мероприятия", planEvent),
    widget.NewFormItem("Исполнители", executor),
    widget.NewFormItem("Количество обуч.", count),
)

btnSave := widget.NewButton("OK", func() {
    dataSend := fmt. Sprintf("%s %s %s", planEvent.Text, executor.Text, count.Text)
    
    // оптправка данных на сервер
})

btnExit := widget.NewButton("Выход", func() {
    a.Quit()
})

w.SetContent(
    widget.NewVBox(
        form,
        layout.NewSpacer(), // add empty block
        widget.NewHBox(layout.NewSpacer(), btnSave, btnExit), // add button block
    ))


w.Resize(fyne.NewSize(480, 200))
a.Settings().SetTheme(theme.LightTheme())

w.ShowAndRun()

В данном коде мы создаем новое приложение (app.New), а в нем новое окно на котором будут размещаться виджеты (элементы управления).

Затем мы создаем 3 поля ввода с помощью NewEntry и помещаем их на форму, через NewFormItem.

Далее идет создание 2-х кнопок NewButton, которые будут помещены под формой. Кнопка btnSave будет отчечать за чтение и отправку данных, а btnExit — за выход из приложения.

После того как мы определились с виджетами их надо разместить в окне, для этого служит функция SetContent. В этой фунукции мы добавляем вертикальный блок для виджетов, а затем добавляем горизонтальный блок для кнопок.

После того как произошло размещение всех виджетов, я произвел недольшую настройку размеров окна приложения и темы оформления.

Ну и соответственно ShowAndRun стартует само приложение.

Для отправки данных на сервер я использую простой текстовый формат с разделителями в виде пробела.

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

Полный код клиента можно посмотерть в репозитории.

Серверная часть

Сначала я хотел делать отображение записей из БД в этом приложении, но к сожалению не нашел готового виджета.

При запуске серверная часть стартует внутренний сервер и ждет входящих соедиенний. Когда соедиенние устанавливается, сервер принимает данные и сохряняет их в базу, после чего сообщает клиенту что операция произведена удачно.

Полный код сервера можно посмотерть в репозитории.

Заключение

На протяжении всей работы мне очень не хватало документации, поэтому приходилось постоянно лазить по исходному коду и примерам. Также набор виджетов очень беден, но, возможно, это вопрос времени, так как продукт молодой.

В целом Fyne еще довольно сырой и использовать его для чего-то серьезней чем простой формочки представляется слабо возможным.

Так же я полагаю, что быстрее до ума доведут Flutter для декстопных приложений, нежели Fyne.

Please enable JavaScript to view the comments powered by Disqus. comments powered by

GTK + 3 / Sudo Null IT News

I decided to write one cross-platform desktop application on Go . Made a CLI version, everything works fine. Moreover, Go Cross-compilation is supported. Everything is fine in general. But I also needed a GUI version. And then it began …


Library selection (binding) for GUI

The application had to be cross-platform.
Therefore, it should compile under Windows , GNU / Linux and macOS .
The choice fell on such libraries:


Electron and other frameworks that pull Chromium and node.js with them , I threw away as they weigh quite a lot, they also eat up a lot of operating system resources.

Now a little about each library.


gotk3

Binding of the library GTK + 3 . Coverage is not all possibilities, but all the main presence.

Compiled application using the standard go build. Cross-platform compilation is possible, with the exception of macOS . Only with macOS you can compile for this OS, and with macOS you can also compile under Windows + GNU / Linux .

The interface will appear natively for GNU / Linux , Windows (you will need to specify a special theme). For macOS it will not look native. It is possible to get out only if it is a terrible topic that will emulate the native elements of macOS .


therecipe / qt

Binding the Qt 5 library . Support for QML, standard widgets. In general, many people advise this binding.

Compiled using a special command qtdeploy. In addition to the desktop platforms, there are also mobile ones. Crosscompilation takes place using Docker . For Apple operating systems , you can only compile with macOS .

At desire on Qt it is possible to achieve that the interface looked natively on desktop OS.


zserge / webview

The library, which was originally written in C , the author has screwed it to many languages, including Go . Native webview is used to display: WindowsMSHTML , GNU / Linuxgtk-webkit2 , macOSCocoa / WebKit . In addition to the Go code, you will need to pee on JS , well, HTML is useful.

Compiled with go build, cross- compilation is possible with xgo .

Looks native can as far as the standard browser allows.


Selection

Why did I choose gotk3 ?

In therecipe / qt, I didn’t like the application’s very complicated build system, they even made a special command.

zserge / webview does not seem to be bad, it will not weigh much, but still this is a webview and there may be standard problems that occur in such applications: something may go somewhere. And this is not Electron , where the advanced Chromium is always bundled , and everything can go to some old Windows . And besides, you also have to write on JS .

gotk3 I chose as something in between. You can build a standard go build, it looks acceptable, and indeed I love GTK + 3 !

In general, I thought everything would be easy. And that for nothing about Go say that in it a problem with GUI . But how am I wrong …


Getting started

Install everything from gotk3 ( gtk , gdk , glib , cairo ) to yourself:

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

Also, your system should have the GTK + 3 library itself in development.


GNU / Linux

In Ubuntu :

sudo apt-get install libgtk-3-dev

In Arch Linux :

sudo pacman -S gtk3

macOS

Via Homebrew :

 brew install gtk-mac-integration gtk+3

Windows

Everything is not so simple here. The official instructions suggest using MSYS2 and already do everything in it. Personally, I wrote code on other operating systems, and did cross-compilation for Windows in Arch Linux , which I hope to write soon.


Simple example

Now we write a small file with the code main.go:

package main
import (
    "log""github.com/gotk3/gotk3/gtk"
)
funcmain() {
    
    gtk.Init(nil)
    
    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.Main()
}

You can compile using the command go build, and then run the binary. But we just run it:

go run main.go

After launch, we get a window of this type:

Congratulations! You have a simple app from README gotk3 !

More examples can be found on Github gotk3 . I will not disassemble them. Let’s better deal with what is not in the examples!


Glade

There is such a thing for Gtk + 3Glade . This is the GUI Designer for GTK + . It looks like this:

In order not to create each element manually and not to place it somewhere in the window with the help of a program code, you can distribute the entire design in Glade . Then save everything to an XML-like * .glade file and load it already through our application.


Install glade


GNU / Linux

It is easy to install the glade in GNU / Linux distributions . In some Ubuntu it will be:

sudo apt-get install glade

In Arch Linux :

sudo pacman -S glade

macOS

In downloads from the official site is very old build. Therefore, it is better to install via Homebrew :

brew install glade

And then run:

glade

Windows

You can download the latest version here . I personally did not install it on Windows at all, so I don’t know about the stability of Glade work there .


Simple application using Glade

In general, I designed a window like this:

Saved and received file main.glade:

<?xml version="1.0" encoding="UTF-8"?><interface><requireslib="gtk+"version="3.20"/><objectclass="GtkWindow"id="window_main"><propertyname="title"translatable="yes">Пример Glade</property><propertyname="can_focus">False</property><child><placeholder/></child><child><objectclass="GtkBox"><propertyname="visible">True</property><propertyname="can_focus">False</property><propertyname="margin_left">10</property><propertyname="margin_right">10</property><propertyname="margin_top">10</property><propertyname="margin_bottom">10</property><propertyname="orientation">vertical</property><propertyname="spacing">10</property><child><objectclass="GtkEntry"id="entry_1"><propertyname="visible">True</property><propertyname="can_focus">True</property></object><packing><propertyname="expand">False</property><propertyname="fill">True</property><propertyname="position">0</property></packing></child><child><objectclass="GtkButton"id="button_1"><propertyname="label"translatable="yes">Go</property><propertyname="visible">True</property><propertyname="can_focus">True</property><propertyname="receives_default">True</property></object><packing><propertyname="expand">False</property><propertyname="fill">True</property><propertyname="position">1</property></packing></child><child><objectclass="GtkLabel"id="label_1"><propertyname="visible">True</property><propertyname="can_focus">False</property><propertyname="label"translatable="yes">This is label</property></object><packing><propertyname="expand">False</property><propertyname="fill">True</property><propertyname="position">2</property></packing></child></object></child></object></interface>

That is, we got a window window_main( GtkWindow) in which inside the container ( GtkBox), which contains an input field entry_1( GtkEntry), a button button_1( GtkButton) and a label label_1( GtkLabel). In addition, there are still attributes of sampling (I set up a bit), visibility and other attributes that Glade added automatically.

Let’s now try to download this presentation in our main.go:

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

Run again:

go run main.go

And we get:

Hooray! Now we form submission hold XML -like main.gladefile and code main. go!


Signals

The window starts up, but let’s add interactivity. Let the text from the input field when you click on the button will fall into the label.

To do this, first we get the elements of the input field, the button and the label in the code:


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)

I do not handle errors that the function returns GetObject()in order to make the code more simple. But in a real working application they must be processed.

Good. With the code above, we get our form elements. And now let’s process the signal clickedbutton (when the button is pressed). The GTK + signal is essentially a reaction to an event. Add the code:


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

Now run the code:

go run main.go

After entering some text in the field and clicking on the Go button, we will see this text in the label:

Now we have an interactive application!


Conclusion

At this stage, everything seems simple and does not cause difficulties. But I had difficulties with cross- compilation (after all, gotk3 compiles with CGO ), integration with operating systems and the file selection dialog. I even added a native dialogue to the gotk project . Also in my project needed internationalization. There are some features too. If you are interested to see it all now in code, then you can see here .

The source codes of the examples from the article are here .

And if you want to read the sequel, you can vote. And if it turns out to be interesting to someone, I will continue to write.

Кросс-компиляция GUI программы на Go + GTK3 (mingw64 + golang + gotk3)

Настройка docker контейнера для кросс-компиляции GUI программы на GTK3 и golang (gotk3) в Linux под Windows.

Примечание

Я потратил много времени чтобы настроить окружение для cross-compiling gotk3 в рабочей Ubuntu 16.04 — у меня ничего не вышло. После установки доступных пакетов mingw-w64 не хватало header-файлов, которые я попытался добавить вручную:

sudo ln -s /usr/include/libintl.h /usr/x86_64-w64-mingw32/include/
sudo ln -s /usr/include/features.h /usr/x86_64-w64-mingw32/include/
sudo ln -s /usr/include/stdc-predef.h /usr/x86_64-w64-mingw32/include/
sudo ln -s /usr/include/x86_64-linux-gnu/gnu/ /usr/x86_64-w64-mingw32/include/gnu # gnu/stubs.h

Но, в процессе компиляции лезло много ошибок на этапе линковки. Может не те версии библиотек, но возиться вручную не было желания.

Настройка window окружения — тот еще геморой. Установка msys2 с пакетом mingw32, настройка переменных окружения GOPATH, GOROOT, PATH.. Я забил.

В итоге я понял, что недостающие header-файлы libintl.h, features.h, stdc-predef.h, gnu/stubs.h содержит пакет mingw-w64-gtk3. И этот пакет доступен только под Arch Linux.

Я подумал о docker-контейнере на базе Arch Linux и настройка заняла чуть более часа.

1. Качаем образ docker https://hub.docker.com/r/nerzhul/archlinux-mingw64-gcc:

docker pull nerzhul/archlinux-mingw64-gcc:5.0.4

2. Запускаем контейнер и расшариваем папку с проектом на gotk:

docker run -it -v ~/apps/go/src/bitbucket.org/kmmedia/kmm-subjects-activator/:/project nerzhul/archlinux-mingw64-gcc:5.0.4 bash

3. Обновить версии пакетов:

pacman -Syu --noconfirm

4. Дополнение команд и пакетов pacman (можете пропустить этот шаг):

pacman -S bash-completion --noconfirm
source /usr/share/bash-completion/bash_completion
#pacman -Ss nvi --noconfirm # рекомендуют ставить и этот пакет Я не уверен, что это необходимо

5. Устанавливаем зависимости для проекта gotk:

pacman -S git go nano
pacman -S cairo pango pkg-config gtk3
go get -tags gtk_3_24 github. com/gotk3/gotk3/gtk github.com/gotk3/gotk3/gdk github.com/gotk3/gotk3/glib github.com/gotk3/gotk3/cairo

6. Добавляем AUR (пользовательский репозиторий) и ставим пакет mingw-w64-gtk3:

nano /etc/pacman.conf
```
[ownstuff]
SigLevel = Optional TrustAll
Server = http://martchus.no-ip.biz/repo/arch/$repo/os/$arch
```
pacman -S mingw-w64-gtk3
Внимание!

Если после установки пакета вы получаете ошибки «Error ….. missing required signature» — добавьте ключи:

pacman-key --init
pacman-key --populate archlinux

7. Команда компиляции main.go (выполнять также в консоли arch, в каталоге проекта /project):

CGO_CFLAGS_ALLOW=".*" CGO_LDFLAGS_ALLOW=".*" \
    PKG_CONFIG_PATH=/usr/x86_64-w64-mingw32/lib/pkgconfig CC=x86_64-w64-mingw32-gcc CGO_ENABLED=1 \
    GOOS=windows GOARCH=amd64 go build -v -tags gtk_3_24 -gcflags "-N -l" -ldflags "-s -w -H=windowsgui" -o main-windows-amd64. exe main.go

Желаю успехов!

Ошибки, с которыми я столкнулся при настройке окружения/зависимостей Ubuntu 16.04 для кросс-компиляции gotk3 приложения:

#: Error: github.com/gotk3/gotk3/gtk/label.go:12:2: build constraints exclude all Go files in ~/apps/go/src/github.com/gotk3/gotk3/pango
#: Error: gcc: error: unrecognized command line option ‘-mthreads’
#: Error: /usr/include/glib-2.0/glib/gi18n.h:23:21: fatal error: libintl.h: No such file

#go, #gtk+, #gotk3, #cross-compiling, #mingw-w64, #windows gui

Изменение GUI в CS:GO — Руководства и обновления CS:GO

CS:GO в этом году исполнилось 3 года, и последние 2 года общий вид CS:GO не менялся. Это всё же поднадоедает, поэтому умельцы сделали пользовательские изменения для CS:GO. Они затрагивают GUI и всё, что с ним связанно.

Что же такое GUI? Как его изменить? Где скачать GUI для CS:GO? Это вы узнаете в этой статье!

Сначала нужно разобраться что такое GUI. Google выдаёт нам такую информацию:

GUI (Graphical user interface — графический интерфейс пользователя) – это разновидность пользовательского интерфейса, в котором все элементы (кнопки, меню, пиктограммы, списки) представленные пользователю на дисплее выполнены в виде картинок, графики.

Итак, из этого следует, что GUI это и есть иконки здоровья, количества патронов и т.д.

Скачать эти самые GUI вы сможете именно в этой статье! Ниже будут приведены две лучшие GUI на наш взгляд и по оценке других пользователей\порталов.


Первая из них — righT.gui. Этот проект создан русскими ребятами, поэтому на него стоит обратить внимание. Этот GUI заменяет как меню, так и остальные части игры.

Скачать его вы сможете по этой ссылке — КЛИК