"Привіт, світе" в GTK

А тепер - за програму з елементом керування (кнопкою). Це - класичний "привіт світе" (hello world) для GTK.

#include <gtk/gtk.h>

/* Ця функцiя викликається системою. Аргумент данних iгнорується
 * в цьому прикладi. Бiльше про зворотнi виклики - нижче. */
void hello( GtkWidget *widget,
            gpointer   data )
{
/* Програми пiд GTK, в яких зустрiчається кирилиця в повiдомленнях
 * потрiбно записувати в юнiкодi (UTF-8) */
    g_print ("Привiт, свiте бiлий\n");
}

gint delete_event( GtkWidget *widget,
                   GdkEvent  *event,
                   gpointer   data )
{
    /* Якщо функцiя обробки сигналу "delete_event" повертає FALSE,
     * GTK пошле сигнал "destroy". Повертання TRUE означає, що ви
     * не бажаєте, аби вiкно було знищено.
     * Це корисно, коли ви хочете, щоб програма перепитала чи користувач
     * дiйсно хоче завершити роботу. */
    g_print ("delete event occurred\n");
    /* Змiнiть TRUE на FALSE i головне вiкно буде знищено при
     * подiї "delete_event". */
    return TRUE;
}

/* Iнша функцiя зворотнього виклику (callback) */
void destroy( GtkWidget *widget,
              gpointer   data )
{
    gtk_main_quit ();
}

int main( int   argc,
          char *argv[] )
{
    /* GtkWidget is the storage type for widgets */
    GtkWidget *window;
    GtkWidget *button;

    /* Цей виклик робиться у всiх програмах пiд GTK. Аргументи беруться
     * з командної строки i повертаються в програму. */
    gtk_init (&argc, &argv);

    /* створюєм нове вiкно */
    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);

    /* Коли вiкно отримує сигнал "delete_event" (його дає вiконний менеджер,
     * зазвичай пр виборi опцiї "закрити" або при закриттi мишкою по
     * хрестику), ми просимо його викликати функцiю delete_event ()
     * як показано вище. Даннi якi передаються в функцiю зворотнього виклику
     * це - NULL i вони iгноруються. */
    g_signal_connect (G_OBJECT (window), "delete_event",
                      G_CALLBACK (delete_event), NULL);

    /* Тут ми приєднуємо подiю "destroy" до обробника сигналiв.
     * Ця подiя з'являєтьсяколи ми викликаєм gtk_widget_destroy() стосовно
     *  вiкна, або якщо полвертаємо FALSE в обробнику подiї "delete_event". */
    g_signal_connect (G_OBJECT (window), "destroy",
                      G_CALLBACK (destroy), NULL);

    /* Встановлює ширину краю вiкна. */
    gtk_container_set_border_width (GTK_CONTAINER (window), 10);

    /* Створює нову кнопку з написом "Hello World". */
    button = gtk_button_new_with_label ("Hello World");

    /* Коли кнопка отримує сигнал "clicked" - вона викличе функцію
     * hello() , передаючи їй  аргумент NULL .  Функція  hello()
     * описана вище. */
    g_signal_connect (G_OBJECT (button), "clicked",
                      G_CALLBACK (hello), NULL);

    /* Це спричинить знищення вікна викликом gtk_widget_destroy(window)
     * при події "clicked".  Нагадуєм: сигнал знищення може прийти від
     * СКВ (Система Керування Вікнами - "віконний менеджер") */
    g_signal_connect_swapped (G_OBJECT (button), "clicked",
                              G_CALLBACK (gtk_widget_destroy),
                              G_OBJECT (window));

    /* "Запаковує" кнопку в вікно (контейнер gtk). */
    gtk_container_add (GTK_CONTAINER (window), button);

    /* Кінцевий крок - показати новостворений елемент інтерфейсу. */
    gtk_widget_show (button);

    /* і саме вікно */
    gtk_widget_show (window);

    /* Всі прграми під GTK повинні мати gtk_main(). Хід програми тут
     * припиняється і вона очікує на події (натискання клавіш, події
     * від мишки). */
    gtk_main ();

     /* Якщо ви - особливий збоченець - можете послати gtk_main ()
      * в окремий потік і продовжувати тут свою прогаму, але користі
      * від того буде менше, ніж витрачено праці. */
    return 0;
}

Щоб відкомпілювати свою програму наберіть:

gcc -Wall -g helloworld.c -o helloworld `pkg-config --cflags gtk+-2.0` \
    `pkg-config --libs gtk+-2.0`

Тут використовується програма pkg-config, котру можна отримати з http://www.freedesktop.org . Ця прграма читає *.pc який іде з GTK щоб визначити які опції потрібно компілятору щоб відкомпілювати програми під GTK. pkg-config --cflags gtk+-2.0 видасть список директорій з заголовковими файлами pkg-config --libs gtk+-2.0 видасть список бібліотек, які потрібно підключити і список директорій, де їх шукати. В вишенаведеному прикладі вони можуть бути об'єднаними в один вираз: pkg-config --cflags --libs gtk+-2.0

Зверніть увангу на обернені апострофи в вищенаведеному прикладі - це важливо (вони вказують на те, що результати виконання пограми pkg-config ідуть як параметри компілятору, інакше - оболонка пердасть pkg-config як один з параметрів компілятору і ви отримаєте дулю з маком, а не прогаму ;D ).

Бібліотеки, які, зазвичай, підключаються:

  • Бібліотека GTK (-lgtk) -- Бібліотека віджетів, базована на GDK.
  • Бібліотека GDK (-lgdk), the Xlib wrapper.
  • Бібліотека gdk-pixbuf (-lgdk_pixbuf), бібліотека керування образами (картинками).
  • Бібліотека Pango (-lpango) Для інтернаціоналізованого тексту.
  • Бібліотека gobject(-lgobject), містить тип системи, на якій базується GTK.
  • Бібліотека gmodule (-lgmodule), яка використовується для завантаження розширень часу виконання.
  • Бібліотека GLib (-lglib), містить змішані функції; тільки g_print() використовувалась в конкретно в цьому прикладі. GTK побудований над GLib таким чином ви завжди потребуєте цю бібліотеку.
  • Бібліотека Xlib (-lX11)яка використовується в GDK.
  • Бібліотека Xext (-lXext). Вона містить функції для "shared memory pixmaps" та інших розширень X.
  • Математична бібліотека (-lm). GTK використовує її з різних причин (тобто її не треба підключати явно).