Теорія сигналів та зворотніх викликів

В версії 2.0 сигнальна система була пернесена з GTK до GLib, ось чому функції і типи, що описуються в цьому розділі мають префікс "g" а не "gtk". Ми не будемо заглиблюваатись в деталі, що до додаткових можливостей, які дає сигнальна система GLib 2.0 порівняно з сигнальною системою GTK 1.2 .

Пред тим, як розглянути в деталі Привіт, світе ми обговоримо сигнали і функції зворотнього виклику (ФЗВ)("колбеки" -- якось не звучить). GTK -- набір інструментів, керований подіями, що означає те, що воно "засинає" на функції gtk_main() поки не виникне якась подія і керування не передасться на відповідну функцію.

Ця передача керування базується на уявленні про "сигнали". (Зауважем, що ці "сигнали" -- не те саме, що юніксові системні сигнали, і впроваджені без їх використання, хоча, термінологія -- майже ідентична). Коли з'являється подія, така як натиснення кнопки миші, відповідна подія буде "випущеною" елементом інтерфейсу (ЕІ), на якому був курсор миші. Так GTK робить більшість своєї корисної роботи. Є сигнали, які успадковують всі елементи інтерфейсу, такі, як "destroy", і є сигнали, специфічні для для певного типу ЕІ, наприклад, "toggled" для для кнопки вибору. Це рбиться з використанням таких функцій, як ця:

gulong g_signal_connect( gpointer      *object,
                         const gchar   *name,
                         GCallback     func,
                         gpointer      func_data );

Де перший аргумент -- ЕІ, який буде посилати сигнал, другий -- ім'я сигналу, який ви бажаєте обробляти, третій -- функція, яка буде викликана, коли з'явиться сигнал і четвертий -- данні, які передадуться цій функції.

Функція, вказана в третьому аргументі називається "функцією зворотнього виклику", і загалом, має мати такий вигляд:

void callback_func( GtkWidget *widget,
                    gpointer   callback_data );

Де перший аргумент -- покажчик на ЕІ, котрий посилає сигнал, і другий -- покажчик на данні, передані як останній аргумент функції g_signal_connect(), як показано вище.

Зауважим, що вище наведена декларація -- загальний приклад, адже деякі специвічні сигнали ЕІ ґенерують різні викликаючі параметри.

Інший виклик, використаний в прикладі Првіт, світе :

gulong g_signal_connect_swapped( gpointer     *object,
                                 const gchar  *name,
                                 GCallback    func,
                                 gpointer     *slot_object );

g_signal_connect_swapped() -- те саме, що і g_signal_connect() тільки ФЗВ використовує лише один аргумент -- покажчик на об'єкт GTK. Отже коли використовується ця фуекція, для приєднання сигналів, ФЗВ мусьть мати вигляд:

void callback_func( GtkObject *object );

де object -- зазвичай є ЕІ. Як правило, ми не будем використовувати g_signal_connect_swapped() однак, вона зазвичай використовується, щоб викликати функцію GTK, яка використовує лише один аргумент, як у випадку з нашим прикладом Привіт, світе.

Підставою для того, щоб мати дві функції для приєднання сигналів є прагнення дозволити функціям зворотнього виклику мати різну кулькість аргументів. Багато функцій бібліотеки GTK мають лише один аргумент -- пойнтер на GtkWidget, отже, ви можете захотіти використати g_signal_connect_swapped() для них. Тоді як вашим функціям можуть знадобитись додаткові аргументи.