обработка событийсигналы gtk для действий высшего уровня (high-level) мы уже обсудили, такие как выбор пункта меню. но иногда полезно использовать сигналы низкого уровня (lower-level), такие как передвижение курсора мышки, или нажатие клавиши. обработчики для этих сигналов имеют дополнительный параметр, который является указателем на структуру, содержащую информацию о событии. например, обработчики события движения передают указатель на структуру gdkeventmotion, которая частично выглядит так:
type - устанавливает тип события, в этом случае gdk_motion_notify, window - окно в котором произошло событие. x и y - координаты произошедшего события. state - определяет состояние модификатора, когда произошло событие ( то есть определяет, какие модифицирующие клавиши и кнопки мыши были нажаты). это - поразрядное или, как например:
для других сигналов, чтобы определить, какое событие произошло, мы вызываем gtk_signal_connect(). но мы также должны сообщить gtk о каких событиях нас следует уведомлять. это делается функцией:
вторая часть определяет события, которыми мы интересуемся. это - поразрядное или констант, которые определяют различные типы событий. типы события:
есть несколько нюансов которые нужно соблюсти вызывая gtk_widget_set_events(). первое - нужно вызвать эту функцию перед тем как будет создано окно x для виджета gtk. практически вы должны вызвать функцию сразу после создания виджета. во вторых - виджет должен иметь ассоциированное x окно(x window). для эффективности, многие типы виджетов не имеют собственного окна, а отображаются в окне их родителя. вот эти виджеты:
чтобы перехватывать события для этих виджетов, вы должны использовать виджет eventbox. см. раздел eventbox. для нашей программмы рисования, мы должны знать, когда кнопка мыши нажата и мышь перемещена, таким образом мы определяем gdk_pointer_motion_mask и gdk_button_press_mask. мы также должны знать, когда перерисовать наше окно, таким образом мы определяем gdk_exposure_mask. хотя нам необходимо уведомление об изменении размера нашего окна через конфигурацию события, мы не должны определять передачу флага gdk_structure_mask, потому что это автоматически определено для всех окон. однако, как оказывается есть проблема с определением gdk_pointer_motion_mask. это заставит сервер добавлять новое событие передвижения в очередь событий каждый раз, когда пользователь перемещает мышь. вообразите, что нам требуется 0.1 секунды, чтобы обработать событие движения, но в очередь x сервера поступает новое событие передвижения каждые 0.05 секунды. если пользователь рисовал в течении 5 секунд, нам потребуется ещё 5 секунд для перехвата после освобождения кнопки мышки! но нам нужно получить только одно событие движения для каждого случая, который мы обрабатываем. это можно сделать определив gdk_pointer_motion_hint_mask. мы определяем gdk_pointer_motion_hint_mask, когда сервер в первый раз сообщает нам о передвижении указателя после входа в наше окно, или после нажатия или освобождения кнопки. последующие события движения будут подавлены, пока мы явно не спросим положение указателя, используя функцию:
( есть другая функция gtk_widget_get_pointer(), которая имеет более простой интерфейс, но оказывается, не очень полезной, так как только восстанавливает положение мышки в состояние не нажатых кнопок.) код установки событий для нашего окна выглядит так:
мы сохраним "expose_event" и "configure_event" обработчики позже. обработчики "motion_notify_event" и "button_press_event" довольно просты:
|