пошаговое изучение hello worldтеперь рассмотрим теорию на примере программмы helloworld. начнем с функции обратного вызова которая вызывается при нажатии на кнопку ("clicked"). мы игнорируем и виджеты и данные в этом примере, но не трудно понять что они делают. в следующем примере мы будем использовать данные аргументов для определения того, какая кнопка была нажата.
следующий обратный вызов (callback) является специальным. "delete_event" происходит когда оконный менеджер сообщает об этом событии программме. мы можем выбирать что сделать с этим событием. проигнорировать его, создавая своего рода ответ, или просто выйти из программмы. значение которое вы возвращаете в данном обратном вызове (callback) сообщает gtk какое действие выполнить. возвращая true, мы сообщаем что не хотим создать сигнал "закрыть" ("destroy"), продолжая выполнение нашей программмы. возвращая false, мы создаем сигнал "закрыть" ("destroy"), который будет выполнен обработчиком сигналов.
вот другая функция обратного вызова которая сообщает программме о выходе calling gtk_main_quit(). когда контроль переходит к ней, она сообщает gtk о том, что нужно прекратить выполнение gtk_main.
как вы знаете, все программмы имеют функцию main(), gtk программмы тоже не являются исключением.
следующие строки объявляют указатели на структуры имеющих тип gtkwidget. они используются для создания окна и кнопки.
и снова наш gtk_init(), как и прежде инициализирует набор инструментов, и разбирает найденные аргументы командной строки. любой аргумент не входящий в список допустимых для gtk_init() передаётся для дальнейшего разбора вашей программмой.
создание нового окна, достаточно прямолинейно. память распределяется для указателя gtkwidget *window таким образом указатель становится структурой. окно создается, но оно не будет показано на дисплее пока мы не вызовем gtk_widget_show(window) функцию в нашей программме.
вот два примера вызова обработчика сигналов для объекта, в данном случае окна. здесь перехватываются сигнал "delete_event" и "destroy". первый создается когда мы используем менеджер окон для закрытия окна (window), или когда мы используем в окне объект который вызывает gtk_widget_destroy(). второй создается когда, в обработчик "delete_event", возвращается false. макросы g_object и g_callback проводят преобразование типов, а также делают код более удобочитаемым.
следующая функция используется для установки атрибутов объекта контейнер. это окно имеет внутренний контур в 10 pixels в который не входит не один виджет. есть и другие похожие функции которые будут рассмотрены в секции setting widget attributes и снова макрос gtk_container для преобразования типа.
этот вызов создаёт новую кнопку. выделяет память для новой структуры gtkwidget, инициализирует и создаёт указатель на кнопку. она будет иметь ярлык "hello world".
теперь мы попробуем заставить кнопку выполнить что-нибудь полезное. когда обработчик сигналов получает сигнал "clicked", то вызывается функция hello(). данные игнорируются, таким образом обратным вызовом функции hello() будет null. очевидно, что сигнал "clicked" возникает при нажатии кнопки мыши.
можно также использовать эту кнопку для выхода из программмы. это иллюстрирует что сигнал "destroy" может быть вызван, как менеджером окон, так и нашей программмой. вы можете иметь сколько нужно функций обратного вызова (callback functions), все они будут выполнены после вызова. поскольку функция gtk_widget_destroy() принимает только указатель gtkwidget *widget как аргумент, мы используем здесь функцию g_signal_connect_swapped() вместо straight g_signal_connect().
упаковочные вызовы обсуждаются позже в packing widgets. здесь просто сообщается gtk, что кнопка должна размещаться внутри окна в момент отображения. заметьте, что контейнер gtk может содержать только один виджет. есть другие виджеты, которые обсуждаются позже, разработанные для многократного размещения виджетов.
теперь мы настроили всё необходимое. нужно чтобы gtk мог показать все окно, кнопки с прикрепленными обработчиками сигналов и другие виджеты. для того, чтобы всё окно отображалось сразу со всеми виджетами, его нужно вызывать для отображения последним, иначе при сложных интерфейсах может возникнуть эффект прорисовки виджетов на фоне пустого окна.
и конечно мы запускаем функцию gtk_main() которая ожидает событий x server и при возникновении таковых запускает соответствующие виджеты.
и заключительный вызов после gtk_quit().
теперь когда мы нажимаем на кнопку мыши, виджет gtk button создаёт сигнал "clicked". эту информацию можно использовать для настройки обработчика сигнала таким образом, чтобы он запускал функции соответственно вашего выбора. в нашем примере при создании сигнала "clicked", запускается функция hello() с пустым аргументом null, а затем вызывает следующего обработчика сигналов, который запускает функцию gtk_widget_destroy() с аргументами для закрытия основного окна программмы. она создаёт сигнал "destroy", который вызывает функцию обратного вызова destroy() для простого выхода из gtk программмы. другой вариант, использовать менеджер окон для закрытия программмы при помощи события "delete_event". если в обработчик события "delete_event", возвратить true, то ничего не произойдет и окно останется открытым. возвращенное false заставит gtk создать сигнал "destroy" и выйти из gtk программмы.
|