2012-08-20

GTK+: Первое оконное приложение в Linux


Цель: написать оконное приложение с использдованием библиотек GTK;
Операционная система: Fedora 17;
Язык программирования: С/С++;
Инструменты: Gedit, дебаггер gdb, кмпилятор gcc 4.7.0, termintal
Используемые источники дополнительной информации:
  1. http://www.gtk.org/documentation.php;
  2. Ален И. Голуб Правила программирование Си и Си++ 2001;
  3. http://developer.gnome.org/gtk-tutorial/stable/c39.html;
  4. www.unknownroad.com/rtfm/gdbtut/gdbuse.html;
   ... Начнем.
   Статья взята из [3]. Практически, она является переводм. Но здесь я использую свое толкование.
   Итак, нам необходимо написать оконное приложеное. На первый взгляд это может оказаться сложниым. Но в рузультате вы прийдете к выводу, что это даже проще, чем на Window, даже пользуясь удобными средствами разработки.
   Начну с теории. В трех словах. Простая программа с использованием GTK может быть легко написана в одном файле. Для создания оконного оприложения необходимо предворительно установтиь библиотеки (установка которых, в данной статье не обсуждается, автор предполагает, что на компьютере уже установленно все необходимое). Используя диррективу включения необходимо подключить библиотеку gtk.h. В ней находится все необходимое для создания базовых окон и элементов управления и работы с собитиями.
   Так же как и в консольном приложении (в принципе во всех программах С/С++), так и в окнном, точкой входа в программу является функция main(argc, argv[]).
   Наше приложение будет состоять из окна с одной кнопкой по середине. При нажатии на нее в консоль дебаггера будет выводитсья строка "Hello World!!!". Ну конечно! Именно эта строка, а вы как подумали? Это же первое приложение, а традиции нарушать нельзя.
      Одной из особенностей оконных приложений является то, что все действия выполняемые в программой начинаются после возникновения определенного события. Отследив событие тому или иному элементу управления, можно запрограммировать действия программы. При нажатие на кнопке будет отслеживаться собыитие "clicked". Для каждого события создается определенная функция, которая вызывается в результате того или иного события.
   После инициализации приложения, события отслеживатются специальной функцией gtk_main().
   Мы будем отслеживать два события: клик мыши на кнопке, и закрытие окна. Кстати при закрытии окна, на вывод дебаггера будет вызываться функция, которая будет выводить на экран с текстом - "delete event occurred".

   Так, основное я довел, а теперь практика.
   Подключаем библиотеку GTK:
#include <gtk/gtk.h>
Теперь опишем функцию, которая будет выполняться при возникновении событи нажатия мыши по кнопке на форме:
//--------------------------------------------------------------------------------
static void hello( GtkWidget *widget,
                   gpointer   data )
{
    g_print( "Hello World\n" );
}
На первый взгдя такой стиль описания функций может показаться странным, но он улучшает читабельность программы. К тому же можно написать коментарий к каждому аргументу функции. Функция g_print() выводит текст в консоль при работе дебаггера. Очевидно, что аргументом этой функции является выводимый текст.
   Правило 38. Используйте штриховую линию для зрительного разделения подпрограмм  из [2]. Штриховая линия помагает визуально отделить функции друг от друга, и улучшает читабельность программы.
    Также примечательно обратить внимание на правило 42. Выравнивайте скобки вертикально по левой границе [2]. На первый взгляд стиль Кэрнигана может показаться удобным, но это оказывается наоборот, когда размер текста программы увеличивается.

Продолжаем. Событие, закрытия окна:
//--------------------------------------------------------------------------------
static gboolean delete_event( GtkWidget *widget,
                              GdkEvent  *event,
                              gpointer   data )
{
    gtk_main_quit();
    g_print( "delete event occurred\n" );
    return FALSE;
}
Функция gtk_main_quit() выполняет выходи из приложения. После выполнения этого кода, на экран дбеггера выведется текст сообщения и приложение закончит свою работу.

Теперь пишем функцию входа в приложение:
//--------------------------------------------------------------------------------
int main( int  argc,
          char *argv[] )
{
}
Весь нижеприведнный код помещать внутри этой функци.
GtkWidget *window;  // windows object
GtkWidget *button;  // button on the canvas
Первая строка создает объект окна, вторая элемент управления кнопка.
Далее необходимо обработать аргументы запуска программы, если таковы были:
gtk_init( &argc, &argv );
Теперь выполняем код создания окна, непосредственно:
window = gtk_window_new( GTK_WINDOW_TOPLEVEL );
После создания окна необходимо прописать все действия необходимых событий.
Вызов функции delete_event() при закрытии окна
g_signal_connect( window, "delete-event", G_CALLBACK( delete_event ), NULL );
Функция g_signal_connect() используется для обработки событий. Перывый аргумент указывает соыбтие какого элемента упрваления следует отлавливать. Второй аргумент указывает, какое событи необходимо обработать, в нашем случае это уничтожение окна. Третий - указывает на функцию, вызываемую при возникновении события. Четвертый - указатель на данные передваемые вызываемой функции. Вы наверняка заметили, что у hello() и delete_event() есть аргумент   gpointer data. Вот именно в этот аргумент передаются данные.
Может возникнуть вопрос, - "как это окно является элементом управления, ведь window - это окно?". Вообще говоря, все элемнты управления, кнопки, скроллбары, переключатели и т.д., в том числе и окна воспринимаются как окна. Так что, в принципе их можно рассматривать как одно и то же.
Теперь делаем границу 10 пикселей от краев окна:
gtk_container_set_border_width( GTK_CONTAINER( window ), 10 );
Создаем кнопку:
button = gtk_button_new_with_label( "Hello world" );

Как вы уже смогли понять, вышеуказання функция создает кнопку с меткой "Hello World".
Теперь опишем обработку сигнала нажатия кнопки:
g_signal_connect( button, "clicked", G_CALLBACK( callback ), NULL );
Далее, добавляем созданную кнопку на окно:
gtk_container_add( GTK_CONTAINER( window ), button );

Отображем кнопку и окно:
gtk_widget_show( button );
gtk_widget_show( window );
Затем вызываем функцию, отлавилвающую все события окна. По сути дела, функция gtk_main() и запускает работу приложения.
gtk_main();
Ну и на последок возвращаем ноль, при оконочании работы приложения:
return 0;
Сохраняем файл под именем "base.cpp". Теперь нам необходимо скомпелировать наше приложение с возможностью отладки. Делается это так:
    gcc -g base.cpp -o base `pkg-config --cflags --libs gtk+-2.0`

Есть два замечания. Первое, парамент -g нужно ставить перед именем исходно файла, в противном случае компилятор просто выдаст ошибку. Второе - ковычки нужно использовать именно такие, как показано в строке выше. Если использовать символ single quote, компиляции не будет.
   Теперь запускаем программу удобным для вас способом, и наслаждаемся своим произведением искусства.

1 comment:

  1. Anonymous2/2/22 20:59

    Slot machine online casino UK - Lucky Club
    How can I claim a £20 Free bet? · Deposit on slots using debit card at least until the initial £10 deposit amount is luckyclub.live settled. · Deposit bonus up to £500. · All you

    ReplyDelete