Начало работы с GTK+
GTK+ — это набор виджетов. Каждый пользовательский интерфейс, созданный с помощью GTK+, состоит из виджетов. Это реализовано на C с использованием GObject, объектно-ориентированной среды для C. Виджеты организованы в иерархию. Виджет окна является основным контейнером. Пользовательский интерфейс затем создаётся путём добавления кнопок, выпадающих меню, полей ввода и других виджетов в окно. Если вы создаёте сложные пользовательские интерфейсы, рекомендуется использовать GtkBuilder и его язык разметки, специфичный для GTK, вместо ручного сборки интерфейса. Вы также можете использовать графический редактор пользовательского интерфейса, например Glade.
GTK+ — это событийно-ориентированная система. Набор инструментов прослушивает события, такие как щелчок по кнопке, и передает это событие вашему приложению.
Эта глава содержит некоторую справочную информацию, которая поможет вам начать программирование с GTK+. Предполагается, что у вас установлен и готов к использованию GTK+, его зависимости и компилятор C. Если вам необходимо сначала скомпилировать сам GTK+, обратитесь к разделу Компиляция библиотек GTK+ в этом руководстве.
Чтобы начать наше знакомство с GTK, мы начнём с простого приложения GTK на основе сигналов. Эта программа создаст пустое окно размером 200 × 200 пикселей.
Создайте новый файл с указанным ниже содержимым под именем example-0.c.
#include <gtk/gtk.h>
static void
activate (GtkApplication* app,
gpointer user_data)
{
GtkWidget *window;
window = gtk_application_window_new (app);
gtk_window_set_title (GTK_WINDOW (window), "Window");
gtk_window_set_default_size (GTK_WINDOW (window), 200, 200);
gtk_widget_show_all (window);
}
int
main (int argc,
char **argv)
{
GtkApplication *app;
int status;
app = gtk_application_new ("org.gtk.example", G_APPLICATION_FLAGS_NONE);
g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
status = g_application_run (G_APPLICATION (app), argc, argv);
g_object_unref (app);
return status;
}
Вы можете скомпилировать программу выше с помощью GCC, используя:
gcc `pkg-config --cflags gtk+-3.0` -o example-0 example-0.c `pkg-config --libs gtk+-3.0`
Дополнительную информацию о том, как скомпилировать приложение GTK+, см. в разделе Компиляция приложений GTK+ в этом руководстве.
Все приложения GTK+ будут, конечно, включать gtk/gtk.h, в котором объявляются функции, типы и макросы, необходимые для приложений GTK+.
Даже если GTK+ устанавливает несколько заголовочных файлов, только верхний gtk/gtk.h заголовочный файл может быть включён напрямую кодом сторонних разработчиков. Компилятор прервётся с ошибкой, если любой другой заголовочный файл включён напрямую.
В приложении GTK+ функция main() предназначена для создания объекта GtkApplication и его запуска. В этом примере вызывается указатель GtkApplication с именем app и затем инициализируется с помощью gtk_application_new().
При создании GtkApplication вам нужно выбрать идентификатор приложения (имя) и ввести его в gtk_application_new() в качестве параметра. В этом примере используется org.gtk.example, но для выбора идентификатора вашего приложения ознакомьтесь с этим руководством. Наконец, gtk_application_new() принимает GApplicationFlags в качестве входных данных для вашего приложения, если ваше приложение имеет особые потребности.
Далее сигнал активации подключается к функции activate() выше функций main(). Сигнал activate будет отправлен, когда ваше приложение запущено с помощью g_application_run() в строке ниже. Функция gtk_application_run() также принимает в качестве аргументов указатели на счётчик и массив строк аргументов командной строки; это позволяет GTK+ анализировать определённые аргументы командной строки, которые контролируют поведение самого GTK+. Анализируемые аргументы будут удалены из массива, оставив те, которые не распознаны, для анализа вашим приложением.
Внутри g_application_run отправляется сигнал activate(), и затем мы переходим к функции activate() приложения. Внутри функции activate() мы хотим построить наше окно GTK, чтобы оно отображалось при запуске приложения. Вызов gtk_application_window_new() создаст новое окно GtkWindow и сохранит его внутри указателя window. Окно будет иметь рамку, строку заголовка и элементы управления окном в зависимости от платформы.
Название окна устанавливается с помощью gtk_window_set_title(). Эта функция принимает указатель GtkWindow* и строку в качестве входных данных. Так как наш указатель window является указателем GtkWidget, нам нужно привести его к типу GtkWindow*. Но вместо приведения window через (GtkWindow*), window можно привести с помощью макроса . GTK_WINDOW() проверит, является ли указатель экземпляром класса GtkWindow, перед приведением типа, и выведет предупреждение, если проверка завершится неудачно. Дополнительную информацию об этой конвенции можно найти здесь.GTK_WINDOW()
Наконец, размер окна устанавливается с помощью gtk_window_set_default_size, а само окно отображается GTK с помощью gtk_widget_show_all().
При выходе из окна, например, нажатием на X, g_application_run() в главном цикле возвращает число, которое сохраняется в целочисленной переменной "status". После этого объект GtkApplication освобождается из памяти с помощью g_object_unref(). Наконец, целое число status возвращается, и приложение GTK завершается.
Пока программа работает, GTK+ получает события. Это обычно события ввода, вызванные взаимодействием пользователя с вашей программой, а также такие вещи, как сообщения от менеджера окон или других приложений. GTK+ обрабатывает их, и в результате могут испускаться сигналы на ваших виджетах. Подключение обработчиков к этим сигналам — это обычный способ заставить вашу программу что-то делать в ответ на ввод пользователя.
Следующий пример немного сложнее и пытается продемонстрировать некоторые возможности GTK+.
В соответствии со старой традицией языков программирования и библиотек, это называется Здравствуй, мир.
Пример 1. Здравствуй, мир в GTK+
Создайте новый файл с указанным ниже содержимым под именем example-1.c.
#include <gtk/gtk.h>
static void
print_hello (GtkWidget *widget,
gpointer data)
{
g_print ("Hello World\n");
}
static void
activate (GtkApplication *app,
gpointer user_data)
{
GtkWidget *window;
GtkWidget *button;
GtkWidget *button_box;
window = gtk_application_window_new (app);
gtk_window_set_title (GTK_WINDOW (window), "Window");
gtk_window_set_default_size (GTK_WINDOW (window), 200, 200);
button_box = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
gtk_container_add (GTK_CONTAINER (window), button_box);
button = gtk_button_new_with_label ("Hello World");
g_signal_connect (button, "clicked", G_CALLBACK (print_hello), NULL);
g_signal_connect_swapped (button, "clicked", G_CALLBACK (gtk_widget_destroy), window);
gtk_container_add (GTK_CONTAINER (button_box), button);
gtk_widget_show_all (window);
}
int
main (int argc,
char **argv)
{
GtkApplication *app;
int status;
app = gtk_application_new ("org.gtk.example", G_APPLICATION_FLAGS_NONE);
g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
status = g_application_run (G_APPLICATION (app), argc, argv);
g_object_unref (app);
return status;
}
Вы можете скомпилировать программу выше с помощью GCC, используя:
gcc `pkg-config --cflags gtk+-3.0` -o example-1 example-1.c `pkg-config --libs gtk+-3.0`
Как видно из примера example-1.c, он строится на основе example-0.c, добавляя в наше окно кнопку с надписью "Здравствуй, мир". Для этого объявляются два новых указателя GtkWidget, button и button_box. Переменная button_box создаётся для хранения GtkButtonBox, что является способом GTK+ управления размером и расположением кнопок. GtkButtonBox создаётся и присваивается gtk_button_box_new(), который принимает перечисление GtkOrientation в качестве параметра. Кнопки, которые будет содержать этот контейнер, могут храниться либо горизонтально, либо вертикально, но это не имеет значения в данном случае, так как у нас только одна кнопка. После инициализации button_box с горизонтальной ориентацией код добавляет виджет button_box в виджет окна с помощью gtk_container_add().
Далее переменная button инициализируется аналогичным образом. Вызывается gtk_button_new_with_label(), который возвращает GtkButton для хранения внутри button. Затем button добавляется в наш button_box. С помощью g_signal_connect кнопка подключается к функции в нашем приложении, названной print_hello(), так что при нажатии на кнопку GTK вызовет эту функцию. Поскольку функция print_hello() не использует какие-либо данные в качестве входных данных, ей передаётся NULL. print_hello() вызывает g_print() со строкой "Здравствуй, мир", что выведет Здравствуй, мир в терминал, если приложение GTK запускалось из него.
После подключения print_hello(), другой сигнал подключается к состоянию «нажатие» кнопки с помощью g_signal_connect_swapped(). Эта функция похожа на g_signal_connect() с разницей в обработке функции обратного вызова. g_signal_connect_swapped() позволяют указать, что функция обратного вызова должна принимать в качестве параметра, передавая его как данные. В этом случае вызываемой функцией обратного вызова является gtk_widget_destroy(), и ей передаётся указатель window. В результате, при нажатии на кнопку, всё окно GTK уничтожается. В противоположность этому, если для подключения сигнала «нажатие» к gtk_widget_destroy() использовалось бы обычное g_signal_connect(), то уничтожался бы сам button, а не окно. Дополнительную информацию о создании кнопок можно найти здесь.
Остальной код в файле example-1.c идентичен example-0.c. Следующий раздел более подробно расскажет о добавлении нескольких GtkWidgets в ваше приложение GTK.
© 2005–2020 The GNOME Project
Licensed under the GNU Lesser General Public License version 2.1 or later.
https://developer.gnome.org/gtk3/3.20/gtk-getting-started.html