При написании GTK программ
необходимо знать некоторые особенности. Для начала нужно
определиться с терминологией. Все компоненты
графического интерфейса пользователя,
такие как кнопки, переключатели, полосы прокрутки и
прочее, называются виджетами. Для того, чтобы виджет
был отображён на экране, его, во-первых, нужно создать, во-вторых, разместить
(упаковать) в основном окне приложения
или в другой виджете, который упакован
в главное окно, и во-третьих его нужно
сделать видимым.
Создаются все виджеты
практически одинаково, например:
gtk_window_new() или gtk_button_new().
Как правило, в главном
окне приложения требуется размещать
более одного виджета, но в него может быть
упакован только один элемент. Для решения этой задачи
используются специальные виджеты -
контейнеры. Контейнеры бывают
одноместными(родитель GtkBin), то есть в
которые может быть упакован только один
виджет, как, например, в главное окно
приложения, и многоместными (родитель
GtkContainer).
К одноместным относятся
кнопки GtkButton, рамки GtkFrame, окна GtkWindow и
прочее. К многоместным относятся
горизонтальный GtkHBox и вертикальный
контейнер GtkVBox, таблица GtkTable и другие. Причём контейнеры как
правило являются невидимыми элементами
графического интерфейса, но не всегда, например
кнопка, в которую обычно упаковывают
текстовую метку или картинку. В одноместные контейнеры
виджеты упаковываются с помощью функции
gtk_container_add(), В горизонтальный или
вертикальный контейнер: gtk_box_pack_start();// Упаковка
элементов слева направо gtk_box_pack_end();// Упаковка
элементов cправа налево В таблицу: gtk_table_attach();
Отображается виджет
вызовом функции gtk_widget_show(widget) или
gtk_widget_show_all(widget) [для отображения также
и дочерних виджетов]
Как и любое графическое
приложение, программа на GTK может получать
сигналы, аналогично событиям
X-сервера в Unix или сообщениям Windows. Сигналы могут
генерироваться при разных событиях,
например движение мыши, нажатие кнопки,
появление окна и.т.д. Для перехвата сигналов
используется функция gtk_signal_connect(gpointer
*widget,const gchar *name, GCallback func, gpointer data); где: widget - виджет, на котором
событие произошло name - имя сигнала,
подлежащего обработке func - функция обработчика
сигнала, которая будет вызвана при
появлении события data — пользовательские
данные, передаваемые обработчику сигнала
У каждого виджета есть
определённый список сигналов, которые
можно перехватить, например для кнопки
один из сигналов, это "clicked" - нажатие
на кнопке.
Приложение, разработанное
на основе GTK обязательно должно включать: - подключение основного
заголовочного файла GTK (gtk.h) - инициализацию GTK
(gtk_init) - создание и отображение
главного окна приложения (gtk_window_new) - главный цикл приложения
(gtk_main)
Пример простого (не
самого простого) приложения на GTK+
// Иннициализация GTK; gtk_init(&argc,&argv) ; // создаем главное окно window =
gtk_window_new(GTK_WINDOW_TOPLEVEL); // выставляем величину
окантовки внутренней области главного
окна gtk_container_set_border_width(GTK_CONTAINER
(window),20); // Текстовая метка в
окне label = gtk_label_new("Привет
Мир!"); // упаковываем метку в
окно gtk_container_add (GTK_CONTAINER
(window), label); // Сигналы // сигнал ("delete_event")
- принудительное закрытие главного окна gtk_signal_connect(
GTK_OBJECT(window),"delete_event",GTK_SIGNAL_FUNC(gtk_false),NULL
);//не передаем никаких данных в обработчик // сигнал ("destroy")
- уничтожение главного окна gtk_signal_connect(
GTK_OBJECT(window),"destroy",GTK_SIGNAL_FUNC(destroy_window),
NULL); // отображение основного
окна gtk_widget_show_all(window); // главный цикл приложения,
на этой функции приложение "зависает"
вплоть до вызова функции gtk_main_quit() gtk_main(); }
Это приложение рабочее
и оно создаёт окно в котором в центре
написано: Привет Мир!
Немного комментариев:
после инициализации GTK создаём главное
окно. Далее создаём новый
виджет - текстовую метку и упаковываем
её в окно. Кстати, если хочется
использовать русские символы, то текст
программы должен быть в кодировке UTF8.
Подключение обработчиков
сигналов здесь самое интересное. Подключаем обработчики
двух событий главного окна. Событие delete_event -
генерируется при попытке закрытия окна
кнопкой в заголовке с изобжением
"крестика". При появлении этого
события в нашем случае будет вызываться
функция gtk_false(), это встроенная функция,
которая всегда возвращает FALSE(0). Таким образом мв
позволяем закрыть окно. Если в качестве
обработчика написать gtk_true(), то окно стандартным
образом закрыть будет невозможно. Если
требуется при закрытии окна спросить пользователя,
уверен ли он, что хочет закрыть окно, то
можно создать свой обработчик, который будет возвращать
значение в зависимости от ответа
пользователя. Событие destroy генерируется
по возвращении FALSE в обработчике события
delete_event или при вызове функции
gtk_widget_destroy(window) или gtk_object_destroy(window). В нашем случае при
появлении события destroy будет вызвана
наша функция destroy_window(), которая и завершит
работу приложения через gtk_main_quit(). Таким образом, если в
приложении будет выполнена функция
gtk_widget_destroy(window), то обработчик события
delete_event не будет запущен.
Для отображения основного
окна используем функцию
gtk_widget_show_all(window) которая отобразит также и дочерний виджет
label. Потом программа переходит
в режим ожидания, процесс будет крутиться
в gtk_main() до тех пор, пока не нажмём на
"крестик" для закрытия окна.
Для ОС Windows: если нет
желания наблюдать дополнительное
консольное окно, то для компилятора GCC
- задать опцию '-mwindows'. А для Visual С++ можно
где-нибудь в начале приложения написать: #pragma
comment(linker,"/SUBSYSTEM:WINDOWS")// компилировать
в режиме Win, без консоли; но тогда вместо функции
main() придётся использовать WinMain(). Но для отладки рекомендую
его оставить, т.к. всяческие ошибки и
предупреждения GTK вываливаются именно
туда.
Попробуем откомпилировать
первое приложение. Создадим файл main.c и
запишем в него вышеприведенный пример. Примеры Makefile даны ниже. Для компиляции достаточно
выполнить команду make, удалить отладочную
информацию можно командой strip. Если Вы пользуетесь
Visual Studio, то нужно создать консольный
проект с одним файлом main.c.
Причём оболочка должна быть настроена,
как было показано в предыдущем выпуске.