Отправляет email-рассылки с помощью сервиса Sendsay

Практические советы по GTK+

  Все выпуски  

Практические советы по GTK+ Первое приложение



Первое приложение:

При написании 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+

#include <gtk/gtk.h>

void destroy_window(GtkWidget *window, gpointer data)
{
    // завершение работы приложения
    gtk_main_quit();
}

void main(int argc, char* argv[])
{

    GtkWidget *window;
    GtkWidget *label;

    // Иннициализация 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. Причём оболочка должна быть настроена, как было показано в предыдущем выпуске.


Make файл для gcc под Unix:

CC=gcc
FLAGS := $(shell pkg-config --cflags gtk+-2.0)
LIBS := $(shell pkg-config --libs gtk+-2.0)
SOURCES= main.c
app : $(SOURCES)
$(CC) -o $@ $(SOURCES) $(FLAGS) $(LIBS)


Make файл для gcc под Windows:

СС=gcc
FLAGS := $(shell pkg-config --cflags gtk+-2.0)
LIBS := $(shell pkg-config --libs gtk+-2.0)
SOURCES= main.c
app : $(SOURCES)
$(CC) -mwindows -o $@ $(SOURCES) $(FLAGS) $(LIBS)



В избранное