Основной цикл и события
Основной цикл и события — Инициализация библиотеки, основной цикл обработки событий и события
Функции
Типы и значения
| #define | GTK_PRIORITY_RESIZE |
Файлы заголовочных
#include <gtk/gtk.h>
Описание
Перед использованием GTK+ необходимо его инициализировать; инициализация подключается к дисплею системного окна и парсит некоторые стандартные аргументы командной строки. Макрос gtk_init() инициализирует GTK+. gtk_init() завершает приложение в случае возникновения ошибок; чтобы этого избежать, используйте gtk_init_check(). gtk_init_check() позволяет восстановиться после неудачной инициализации GTK+ — вы можете запустить приложение в текстовом режиме.
Как и все наборы инструментов графического интерфейса, GTK+ использует модель программирования, управляемую событиями. Когда пользователь ничего не делает, GTK+ находится в «главном цикле» и ожидает ввода. Если пользователь выполняет какое-либо действие — например, щелчок мыши, — то главный цикл «пробуждается» и передает событие GTK+. GTK+ передает событие одному или нескольким виджетам.
Когда виджеты получают событие, они часто излучают один или несколько «сигналов». Сигналы уведомляют вашу программу о том, что «произошло что-то интересное», вызывая функции, которые вы подключили к сигналу с помощью g_signal_connect(). Функции, подключенные к сигналу, часто называются «обработчиками».
Когда вызываются ваши обработчики, вы обычно выполняете какое-либо действие — например, при нажатии кнопки «Открыть» вы можете отобразить GtkFileChooserDialog. После завершения обработчика GTK+ вернется в главный цикл и будет ожидать дальнейшего пользовательского ввода.
Типичная main() функция для приложения GTK+
Вместо gtk_main() можно использовать главный цикл GLib, хотя это требует немного большего количества набора кода. Смотрите GMainLoop в документации GLib.
Функции
gtk_disable_setlocale ()
void gtk_disable_setlocale (void);
Запрещает gtk_init(), gtk_init_check(), gtk_init_with_args() и gtk_parse_args() от автоматического вызова setlocale (LC_ALL, ""). Вы можете использовать эту функцию, если хотите установить локаль для вашей программы на значение, отличное от локали пользователя, или если хотите установить разные значения для разных категорий локали.
Большинству программ не нужно вызывать эту функцию.
gtk_get_default_language ()
PangoLanguage *
gtk_get_default_language (void); Возвращает PangoLanguage для языка по умолчанию, который в настоящее время используется. (Обратите внимание, что это может измениться в течение срока службы приложения.) Язык по умолчанию определяется текущей локалью. Он определяет, например, использует ли GTK+ направление текста справа налево или слева направо.
Эта функция эквивалентна pango_language_get_default(). Подробности см. в этой функции.
gtk_get_locale_direction ()
GtkTextDirection
gtk_get_locale_direction (void); Получает направление текущей локали. Это ожидаемое направление чтения текста и пользовательского интерфейса.
Эта функция зависит от установки текущей локали с помощью setlocale() и по умолчанию установит направление GTK_TEXT_DIR_LTR. GTK_TEXT_DIR_NONE никогда не будет возвращено.
GTK+ устанавливает направление текста по умолчанию в соответствии с локалью во время gtk_init(), и обычно вы должны использовать gtk_widget_get_direction() или gtk_widget_get_default_direction() для получения текущего направления.
Эта функция необходима только в редких случаях, когда локаль изменяется после того, как GTK+ уже был инициализирован. В этом случае вы можете использовать ее для обновления направления текста по умолчанию следующим образом:
Возвращает
GtkTextDirection текущей локали
С: 3.12
gtk_parse_args ()
gboolean gtk_parse_args (int *argc,char ***argv);
Парсит аргументы командной строки и инициализирует глобальные атрибуты GTK+, но фактически не открывает соединение с дисплеем. (См. gdk_display_open(), gdk_get_display_arg_name())
Любые аргументы, используемые GTK+ или GDK, удаляются из массива, и argc и argv обновляются соответствующим образом.
Нет необходимости явно вызывать эту функцию, если вы используете gtk_init() или gtk_init_check().
Обратите внимание, что многие аспекты GTK+ требуют подключения к дисплею для работы, поэтому этот способ инициализации GTK+ действительно полезен только для специализированных случаев использования.
Параметры
argc | указатель на количество аргументов командной строки. | [inout] |
argv | указатель на массив аргументов командной строки. | [array длина=argc][inout] |
gtk_init ()
void
gtk_init (int *argc,
char ***argv); Вызовите эту функцию перед использованием других функций GTK+ в ваших приложениях графического интерфейса. Она инициализирует всё необходимое для работы инструментария и парсит некоторые стандартные опции командной строки.
Хотя ожидается, что вы передадите параметры argc , argv из main() в эту функцию, возможно передать NULL, если argv недоступен или обработка командной строки не требуется.
argc и argv соответственно корректируются, так что ваш собственный код никогда не увидит эти стандартные аргументы.
Обратите внимание, что существуют альтернативные способы инициализации GTK+: если вы вызываете gtk_parse_args(), gtk_init_check(), gtk_init_with_args() или g_option_context_parse() с группой опций, возвращенной gtk_get_option_group(), вам не нужно вызывать gtk_init().
И если вы используете GtkApplication, вам не нужно вызывать ни одну из функций инициализации; обработчик «startup» делает это за вас.
Эта функция завершит вашу программу, если по какой-либо причине не удалось инициализировать систему окон. Если вы хотите, чтобы ваша программа переключилась на текстовый интерфейс, вам нужно вызвать gtk_init_check() вместо этого.
Начиная с версии 2.18, GTK+ вызывает signal (SIGPIPE, SIG_IGN) во время инициализации, чтобы игнорировать сигналы SIGPIPE, так как их почти никогда не нужно обрабатывать в графических приложениях. Если вам нужно обработать SIGPIPE по какой-либо причине, сбросьте обработчик после gtk_init(), но имейте в виду, что другие библиотеки (например, libdbus или gvfs) могут выполнять подобные действия.
Параметры
gtk_init_check ()
gboolean gtk_init_check (int *argc,char ***argv);
Эта функция выполняет ту же работу, что и gtk_init(), за исключением одного изменения: она не завершает программу, если систему окон не удаётся инициализировать. Вместо этого она возвращает FALSE в случае ошибки.
Таким образом, приложение может перейти к другим способам общения с пользователем — например, использовать интерфейс curses или командную строку.
Параметры
argc | Адрес параметра | [inout] |
argv | Адрес параметра | [array length=argc][inout][allow-none] |
gtk_init_with_args ()
gboolean gtk_init_with_args (gint *argc,gchar ***argv,const gchar *parameter_string,const GOptionEntry *entries,const gchar *translation_domain,GError **error);
Эта функция выполняет ту же работу, что и gtk_init_check(). Кроме того, она позволяет добавлять собственные параметры командной строки и автоматически генерирует хорошо отформатированный вывод справки. Обратите внимание, что после вывода справки программа будет завершена.
Параметры
argc | Адрес параметра | [inout] |
argv | Адрес параметра | [array length=argc][inout][allow-none] |
parameter_string | строка, отображаемая в первой строке вывода справки, после | [allow-none] |
entries | массив | [array zero-terminated=1] |
translation_domain | домен перевода для перевода вывода справки по опциям в | [nullable] |
error | место для возврата ошибок |
С тех пор: 2.6
gtk_get_option_group ()
GOptionGroup *
gtk_get_option_group (gboolean open_default_display); Возвращает GOptionGroup для параметров командной строки, распознаваемых GTK+ и GDK.
Вы должны добавить эту группу в свой GOptionContext с помощью g_option_context_add_group(), если вы используете g_option_context_parse() для разбора параметров командной строки.
Параметры
open_default_display | открывать ли дисплей по умолчанию при разборе аргументов командной строки |
Возвращаемое значение
GOptionGroup для параметров командной строки, распознаваемых GTK+.
[transfer full]
С тех пор: 2.6
gtk_events_pending ()
gboolean
gtk_events_pending (void); Проверяет, есть ли ожидающие события.
Это можно использовать для обновления пользовательского интерфейса и вызова таймаутов и т. д. во время выполнения трудоёмких вычислений.
Обновление пользовательского интерфейса во время длительных вычислений
gtk_main ()
void gtk_main (void);
Запускает главный цикл до тех пор, пока не будет вызван gtk_main_quit().
Можно вложенно вызывать gtk_main(). В этом случае gtk_main_quit() вернёт результат только для самого внутреннего вызова главного цикла.
gtk_main_level ()
guint
gtk_main_level (void); Запрашивает текущий уровень вложенности главного цикла.
Возвращаемое значение
уровень вложенности текущего вызова главного цикла
gtk_main_quit ()
void gtk_main_quit (void);
Принудительно возвращает результат самого внутреннего вызова главного цикла, когда он получает управление.
gtk_main_iteration ()
gboolean
gtk_main_iteration (void); Выполняет одну итерацию главного цикла.
Если ожидающие события отсутствуют, GTK+ будет блокироваться до тех пор, пока не будет обнаружено следующее событие. Если вам не нужно ожидать, обратитесь к gtk_main_iteration_do() или сначала проверьте, есть ли ожидающие события с помощью gtk_events_pending().
Возвращаемое значение
TRUE, если для самого внутреннего главного цикла был вызван gtk_main_quit()
gtk_main_iteration_do ()
gboolean
gtk_main_iteration_do (gboolean blocking); Выполняет одну итерацию основного цикла. Если доступны какие-либо события, то возвращается или блокируется в зависимости от значения blocking .
Параметры
blocking |
|
Возвращаемое значение
TRUE, если для самого внутреннего основного цикла был вызван gtk_main_quit()
gtk_main_do_event ()
void
gtk_main_do_event (GdkEvent *event); Обрабатывает одно событие GDK.
Эта функция доступна только для фильтрации событий между GDK и GTK+. Вам обычно не нужно вызывать эту функцию напрямую.
Хотя вы не должны вызывать эту функцию напрямую, вам может быть интересно, как именно обрабатываются события. Вот что делает эта функция со событием:
Сжимает события enter/leave notify. Если переданное событие формирует пару enter/leave вместе со следующим событием (полученным с помощью peek из GDK), оба события отбрасываются. Это необходимо для предотвращения задержек при (де)выделении виджетов, пересекаемых указателем.
Определяет виджет, получивший событие. Если виджет определить невозможно, событие отбрасывается, если оно не относится к транзакции INCR.
Затем событие помещается в стек, так что вы можете получить текущее обрабатываемое событие с помощью
gtk_get_current_event().-
Событие отправляется виджету. Если активен захват, все события для виджетов, которые не находятся внутри захваченного виджета, отправляются последнему с несколькими исключениями:
События удаления и уничтожения по понятным причинам все еще отправляются виджету события.
События, которые напрямую связаны с визуальным представлением виджета события.
События leave доставляются виджету события, если раньше ему было доставлено событие enter без связанного события leave.
События drag не перенаправляются, так как не ясно, какими должны быть семантика. Другой интересный момент заключается в том, что все события клавиш сначала передаются через функции key snooper, если они существуют. Прочитайте описание
gtk_key_snooper_install(), если вам нужна эта функция.
После завершения доставки событие извлекается из стека событий.
Параметры
event | Обрабатываемое событие (обычно передается GDK) |
GtkModuleInitFunc ()
void (*GtkModuleInitFunc) (gint *argc,gchar ***argv);
Каждый модуль GTK+ должен иметь функцию gtk_module_init() с этим прототипом. Эта функция вызывается после загрузки модуля.
GtkModuleDisplayInitFunc ()
void
(*GtkModuleDisplayInitFunc) (GdkDisplay *display); Модуль GTK+, поддерживающий несколько дисплеев, может иметь функцию gtk_module_display_init() с этим прототипом. GTK+ вызывает эту функцию для каждого открытого дисплея.
Параметры
display | открытый GdkDisplay |
С момента: 2.2
gtk_true ()
gboolean
gtk_true (void); Функция просто возвращает TRUE.
Это может быть полезно, например, если вы хотите запретить удаление окна. Конечно, этого делать не следует, так как пользователь ожидает реакции при нажатии на значок закрытия окна...
Постоянное окно
int main (int argc, char **argv) { // Initialize i18n support with bindtextdomain(), etc. ... // Initialize the widget set gtk_init (&argc, &argv); // Create the main window mainwin = gtk_window_new (GTK_WINDOW_TOPLEVEL); // Set up our GUI elements ... // Show the application window gtk_widget_show_all (mainwin); // Enter the main event loop, and wait for user interaction gtk_main (); // The user lost interest return 0; }
Возвращаемое значение
gtk_false ()
gboolean
gtk_false (void); Аналогично gtk_true(), эта функция ничего не делает, а всегда возвращает FALSE.
Возвращаемое значение
gtk_grab_add ()
void
gtk_grab_add (GtkWidget *widget); Делает widget текущим захваченным виджетом.
Это означает, что взаимодействие с другими виджетами в том же приложении заблокировано, и события мыши и клавиатуры доставляются этому виджету.
Если widget не реагирует, он не устанавливается в качестве текущего захваченного виджета, и эта функция ничего не делает.
[метод]
Параметры
widget | Виджет, захватывающий события клавиатуры и мыши |
gtk_grab_get_current ()
GtkWidget *
gtk_grab_get_current (void); Запрашивает текущий захват группы окон по умолчанию.
Возвращаемое значение
Виджет, у которого сейчас есть захват, или NULL, если захват не активен.
[transfer none][nullable]
gtk_grab_remove ()
void
gtk_grab_remove (GtkWidget *widget); Удаляет захват из данного виджета.
Вы должны сопоставить вызовы gtk_grab_add() и gtk_grab_remove().
Если у widget нет захвата, эта функция ничего не делает.
[метод]
Параметры
widget | Виджет, отдающий захват |
gtk_device_grab_add ()
void gtk_device_grab_add (GtkWidget *widget,GdkDevice *device,gboolean block_others);
Добавляет захват GTK+ на device, поэтому все события на device и его связанном указателе или клавиатуре (если таковые имеются) доставляются widget. Если параметр block_others равен TRUE, любые другие устройства не смогут взаимодействовать с widget во время захвата.
Параметры
С момента: 3.0
gtk_device_grab_remove ()
void gtk_device_grab_remove (GtkWidget *widget,GdkDevice *device);
Удаляет захват устройства с данного виджета.
Вы должны вызвать функции gtk_device_grab_add() и gtk_device_grab_remove() попарно.
Since: 3.0
gtk_key_snooper_install ()
guint gtk_key_snooper_install (GtkKeySnoopFunc snooper,gpointer func_data);
gtk_key_snooper_install устарело с версии 3.4 и его не следует использовать в новом коде.
Обработка нажатий клавиш не рекомендуется. События должны обрабатываться виджетами.
Устанавливает функцию захвата нажатий клавиш, которая будет вызываться для всех событий нажатия клавиш перед их обычной доставкой.
[skip]
Параметры
snooper | ||
func_data | данные, передаваемые в | [closure] |
Возвращает
уникальный идентификатор для этого захватывателя клавиш, используемый с gtk_key_snooper_remove().
GtkKeySnoopFunc ()
gint (*GtkKeySnoopFunc) (GtkWidget *grab_widget,GdkEventKey *event,gpointer func_data);
Функции захвата нажатий клавиш вызываются перед обычной доставкой событий. Их можно использовать для реализации пользовательской обработки событий нажатий клавиш.
Параметры
grab_widget | виджет, которому будет доставлено событие | |
event | событие нажатия клавиши | |
func_data | данные, предоставленные функции | [closure] |
gtk_key_snooper_remove ()
void
gtk_key_snooper_remove (guint snooper_handler_id); gtk_key_snooper_remove устарело с версии 3.4 и его не следует использовать в новом коде.
Обработка нажатий клавиш не рекомендуется. События должны обрабатываться виджетами.
Удаляет функцию захвата нажатий клавиш с заданным идентификатором.
Параметры
snooper_handler_id | Идентификатор захватывателя нажатий клавиш, который нужно удалить |
gtk_get_current_event ()
GdkEvent *
gtk_get_current_event (void); Получает копию события, обрабатываемого в данный момент GTK+.
Например, если вы обрабатываете сигнал “clicked”, текущее событие будет GdkEventButton, вызвавшее сигнал ::clicked.
Возвращает
копию текущего события или NULL, если текущего события нет. Возвращаемое событие должно быть освобождено с помощью gdk_event_free().
[transfer full][nullable]
gtk_get_current_event_time ()
guint32
gtk_get_current_event_time (void); Если существует текущее событие с отметкой времени, возвращает эту отметку времени, в противном случае возвращает GDK_CURRENT_TIME.
Возвращает
отметку времени текущего события или GDK_CURRENT_TIME.
gtk_get_current_event_state ()
gboolean
gtk_get_current_event_state (GdkModifierType *state); Если существует текущее событие со значением состояния, помещает это значение в state и возвращает TRUE, в противном случае возвращает FALSE.
Параметры
state | место для хранения состояния текущего события. | [out] |
Возвращает
TRUE, если существовало текущее событие и у него было поле состояния
gtk_get_current_event_device ()
GdkDevice *
gtk_get_current_event_device (void); Если существует текущее событие с устройством, возвращает это устройство, в противном случае возвращает NULL.
gtk_propagate_event ()
void gtk_propagate_event (GtkWidget *widget,GdkEvent *event);
Отправляет событие виджету, распространяя его на родительские виджеты, если оно не обработано.
События, получаемые GTK+ от GDK, обычно начинаются в gtk_main_do_event(). В зависимости от типа события, наличия модальных диалоговых окон, захватов и т. д., событие может быть распространено; в этом случае используется эта функция.
gtk_propagate_event() вызывает gtk_widget_event() для каждого виджета, которому он решает отправить событие. Таким образом, gtk_widget_event() является функцией низшего уровня; она просто излучает сигнал “event” и, возможно, событие-специфичный сигнал на виджете. gtk_propagate_event() немного более высокого уровня, а gtk_main_do_event() — самого высокого.
Сказав всё это, вам, скорее всего, не нужно использовать ни одну из этих функций; синтезирование событий редко необходимо. Почти наверняка есть лучшие способы достижения ваших целей. Например, используйте gdk_window_invalidate_rect() или gtk_widget_queue_draw() вместо создания событий expose.
Параметры
widget | виджет GtkWidget | |
event | событие |
Типы и значения
GTK_PRIORITY_RESIZE
#define GTK_PRIORITY_RESIZE (G_PRIORITY_HIGH_IDLE + 10)
Используйте этот приоритет для функциональности, связанной с распределением размеров.
Внутренне GTK+ использует его для вычисления размеров виджетов. Этот приоритет выше, чем GDK_PRIORITY_REDRAW, чтобы избежать изменения размера виджета, который только что был перерисован.
См. также
См. руководство по GLib, особенно GMainLoop и функции, связанные с сигналами, такие как g_signal_connect()
© 2005–2020 The GNOME Project
Licensed under the GNU Lesser General Public License version 2.1 or later.
https://developer.gnome.org/gtk3/3.22/gtk3-General.html