5 минимально-необходимых виджетов для постройки интерфейса программы

Как мы узнали из вступления, каждый визуальный элемент (виджет, или контрол) имеет свою иерархию, напоминающую DOM-дерево HTML. Для построения интерфейса, мы должны научиться комбинировать такие виджеты, и понимать как они управляются.

Итак, виджеты. Их сотни. Однако на данном этапе для построения интерфейса 50% программ, мы изучим всего восемь. Вот они:

GtkBox. Блочный, «невидимый» виджет, который является контейнером, то есть способен размещать в себе другие виджеты, и сам быть размещенным в других. Аналог <div> из мира HTML.

GtkLabel. Строка. Просто текстовая строка.

GtkButton. Кнопка, которую можно нажимать и обрабатывать это нажатие. Может вмещать в себя как картинку, так и текст. Тоже является контейнером, т.е. может содержать другие элементы, однако в отличие от GtkBox, способно обрабатывать на себе специфические сигналы (об этом в следующих уроках).

GtkImage. Картинка, из разных ресурсов: файла, имени иконки, буфера пикселей, которую можно вывести в окне как изображение.

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

Теперь детальнее на примерах.

#!/usr/local/supreme/php/bin/php
<?php
Gtk::init();
function GtkWindowDestroy($widget=NULL, $event=NULL)
{
	Gtk::main_quit();
}
$win = new GtkWindow();
$win->set_default_size(640, 480);
$win->connect("destroy", "GtkWindowDestroy");
$box = new GtkBox(GtkOrientation::HORIZONTAL, 5);
$label_1 = new GtkLabel("Hello");
$label_2 = new GtkLabel("World");
$box->add($label_1);
$box->add($label_2);
$win->add($box);
$win->show_all();
Gtk::main();

Обратите внимание на последовательность встраивания виджетов. Сначала мы встроили наши $label_1 и $label_2 в $box, и лишь затем встроили $box в $win.

Наверняка вы обратили внимание на параметры в скобках GtkBox. Их два, и они просты. Первый параметр — это константа, определяющая расположение дочерних элементов в контейнере. Таких параметров тоже всего два: GtkOrientation::HORIZONTAL и GtkOrientation::VERTICAL. При горизонтальном расположении, последний элемент добавленный в бокс будет располагаться справа от предыдущего (справа налево), при вертикальном — снизу (сверху вниз).

Второй параметр — это отступ в пикселях между элементами в боксе.

Давайте попробуем.

#!/usr/local/supreme/php/bin/php
<?php
Gtk::init();
function GtkWindowDestroy($widget=NULL, $event=NULL)
{
	Gtk::main_quit();
}
$win = new GtkWindow();
$win->set_default_size(640, 480);
$win->connect("destroy", "GtkWindowDestroy");
$box = new GtkBox(GtkOrientation::VERTICAL, 20);
$label_1 = new GtkLabel("Hello");
$label_2 = new GtkLabel("World");
$box->add($label_1);
$box->add($label_2);
$win->add($box);
$win->show_all();
Gtk::main();

Почти все виджеты GTK имеют свойства, устанавливаемые специальными функциями. Большинство из этих функций одинаково для всех виджетов, некоторые функции контейнероспецифичны, т.е. влияют на параметры только виджетов-контейнеров, и только малая часть виджетоспецифичны, т.е. применяются только к конкретным виджетам.

Перечислим несколько функций, которые можно применить к GtkBox.

set_homogeneous(bool). Этот параметр устанавливает одинаковую ширину или высоту для всех объектов в контейнере. Рассмотрим пример, но без кода:

Допустим у нас есть две кнопки, с надписями «Test» и «Click me please«. Пусть размер шрифта у нас будет 8 пикселей. Тогда длина первой кнопки будет 32 пикселя, а длина второй 120 пикселей. Однако, если если установить родительскому контейнеру этих кнопок set_homogeneous в true — обе кнопки будут одинаковой длины в 120 пикселей (по размеру самой большой).

Эта функция действует только для виджетов контейнерного типа.

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

set_size_request(int width, int height). Так мы принудительно устанавливаем размер виджета. В принципе это применимо к любым виджетам, однако стоит учесть, что работать это будет только с тем что способно масштабироваться в системе координат. Размер шрифта так не увеличить.

Кстати, если мы хотим изменить размер только одной стороны, оставив другую как есть — мы можем просто поставить -1 (минус один) для той части, которую не хотим изменять.

set_halign(int GtkAlign) и set_valign(int GtkAlign). Этими функциями мы выравниваем элемент относительно виджета, в котором этот элемент расположен. Здесь лучше использовать числовое значение, взятое из официальной документации GTK: https://docs.gtk.org/gtk3/enum.Align.html

Выравнивание в GTK специфическое, здесь нет левой и правой части, а вместо них есть начальная, конечная, центральная, и заполняемая. Соответственно если нам по вертикали нужно разместить виджет внизу, то мы выбираем GTK_ALIGN_END (число 2, согласно документации), поскольку в нашей классической системе координат, отрисовка идет сверху вниз — сверху START, снизу END.

Поехали дальше, GtkLabel(string $text).

В принципе, как работает этот виджет — мы уже увидели в предыдущем примере.

Особо интересных функций у этого виджета мало, мы упомянем лишь две

set_text(string $text) — изменяет текст у уже существующей GtkLabel.

set_user_markup(bool) — позволяет использовать некоторую разметку в самом тексте, по принципу тегов HTML.