GTK+ 2.0 Tutorial |
||
---|---|---|
Getting Started |
Теперь рассмотрим теорию на примере программы helloworld.
Начнем с функции обратного вызова которая вызывается при нажатии на кнопку ("clicked"). Мы игнорируем и виджеты и данные в этом примере, но не трудно понять что они делают. В следующем примере мы будем использовать данные аргументов для определения того, какая кнопка была нажата.
void hello( GtkWidget *widget,
gpointer data )
{
g_print ("Hello World\n");
}
|
Следующий обратный вызов (callback) является специальным. "delete_event" происходит когда оконный менеджер сообщает об этом событии программе. Мы можем выбирать что сделать с этим событием. Проигнорировать его, создавая своего рода ответ, или просто выйти из программы.
Значение которое вы возвращаете в данном обратном вызове (callback) сообщает GTK какое действие выполнить. Возвращая TRUE, мы сообщаем что не хотим создать сигнал "закрыть" ("destroy"), продолжая выполнение нашей программы. Возвращая FALSE, мы создаем сигнал "закрыть" ("destroy"), который будет выполнен обработчиком сигналов.
gint delete_event( GtkWidget *widget,
GdkEvent *event,
gpointer data )
{
g_print ("delete event occurred\n");
return TRUE;
}
|
Вот другая функция обратного вызова которая сообщает программе о выходе calling gtk_main_quit(). Когда контроль переходит к ней, она сообщает GTK о том, что нужно прекратить выполнение gtk_main.
void destroy( GtkWidget *widget,
gpointer data )
{
gtk_main_quit ();
}
|
Как вы знаете, все программы имеют функцию main(), GTK программы тоже не являются исключением.
int main( int argc,
char *argv[] )
{
}
|
Следующие строки объявляют указатели на структуры имеющих тип GtkWidget. Они используются для создания окна и кнопки.
GtkWidget *window;
GtkWidget *button;
|
И снова наш gtk_init(), как и прежде инициализирует набор инструментов, и разбирает найденные аргументы командной строки. Любой аргумент не входящий в список допустимых для gtk_init() передаётся для дальнейшего разбора вашей программой.
gtk_init (&argc, &argv);
|
Создание нового окна, достаточно прямолинейно. Память распределяется для указателя GtkWidget *window таким образом указатель становится структурой. Окно создается, но оно не будет показано на дисплее пока мы не вызовем gtk_widget_show(window) функцию в нашей программе.
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
Вот два примера вызова обработчика сигналов для объекта, в данном случае окна. Здесь перехватываются сигнал "delete_event" и "destroy". Первый создается когда мы ипользуем менеджер окон для закрытия окна (window), или когда мы используем в окне объект который вызывает gtk_widget_destroy(). Второй создается когда, в обработчик "delete_event", возвращается FALSE. Макросы G_OBJECT и G_CALLBACK проводят преобразование типов, а также делают код более удобочитаемым.
g_signal_connect (G_OBJECT (window), "delete_event",
G_CALLBACK (delete_event), NULL);
g_signal_connect (G_OBJECT (window), "destroy",
G_CALLBACK (destroy), NULL);
|
Следующая функция используется для установки атрибутов объекта контейнер. Это окно имеет внутренний контур в 10 pixels в который не входит не один виджет. Есть и другие похожие функции которые будут рассмотрены в секции Setting Widget Attributes
И снова макрос GTK_CONTAINER для преобразования типа.
gtk_container_set_border_width (GTK_CONTAINER (window), 10);
|
Этот вызов создаёт новую кнопку. Выделяет память для новой структуры GtkWidget, инициализирует и создаёт указатель на кнопку. Она будет иметь ярлык "Hello World".
button = gtk_button_new_with_label ("Hello World");
|
Теперь мы попробуем заставить кнопку выполнить что-нибудь полезное. Когда обработчик сигналов получает сигнал "clicked", то вызывается функция hello(). Данные игнорируются, таким образом обратным вызовом функции hello() будет NULL. Очевидно, что сигнал "clicked" возникает при нажатии кнопки мыши.
g_signal_connect (G_OBJECT (button), "clicked",
G_CALLBACK (hello), NULL);
|
Можно также использовать эту кнопку для выхода из программы. Это иллюстрирует что сигнал "destroy" может быть вызван, как менеджером окон, так и нашей программой.
Вы можете иметь сколько нужно функций обратного вызова (callback functions), все они будут выполнены после вызова. Поскольку функция gtk_widget_destroy() принимает только указатель GtkWidget *widget как аргумент, мы используем здесь функцию g_signal_connect_swapped() вместо straight g_signal_connect().
g_signal_connect_swapped (G_OBJECT (button), "clicked",
G_CALLBACK (gtk_widget_destroy),
G_OBJECT (window));
|
Упаковочные вызовы обсуждаются позже в Packing Widgets. Здесь просто сообщается GTK, что кнопка должна размещаться внутри окна в момент отображения. Заметьте, что контейнер GTK может содержать только один виджет. Есть другие виджеты, которые обсуждаются позже, разработанные для многократного размещения виджетов.
gtk_container_add (GTK_CONTAINER (window), button);
|
Теперь мы настроили всё необходимое. Нужно чтобы GTK мог показать все окно, кнопки с прикрепленными обработчиками сигналов и другие виджеты. Для того, чтобы всё окно отображалось сразу со всеми виджетами, его нужно вызывать для отображения последним, иначе при сложных интерфейсах может возникнуть эффект прорисовки виджетов на фоне пустого окна.
gtk_widget_show (button);
gtk_widget_show (window);
|
И конечно мы запускаем функцию gtk_main() которая ожидает событий X server и при возникновении таковых запускает соответствующие виджеты.
gtk_main ();
|
И заключительный вызов после gtk_quit().
return 0;
|
Теперь когда мы нажимаем на кнопку мыши, виджет GTK button создаёт сигнал "clicked". Эту информацию можно использовать для настройки обработчика сигнала таким образом, чтобы он запускал функции соответственно вашего выбора. В нашем примере при создании сигнала "clicked", запускается функция hello() с пустым аргументом NULL, а затем вызывает следующего обработчика сигналов, который запускает функцию gtk_widget_destroy() с аргументами для закрытия основного окна программы. Она создаёт сигнал "destroy", который вызывает функцию обратного вызова destroy() для простого выхода из GTK программы.
Другой вариант, использовать менеджер окон для закрытия программы при помощи события "delete_event". Если в обработчик события "delete_event", возвратить TRUE, то ничего не произойдет и окно останется открытым. Возвращенное FALSE заставит GTK создать сигнал "destroy" и выйти из GTK программы.
Events |
Moving On |