Библиотека сайта rus-linux.net
Программирование с использованием gtkmm 3. События клавиатуры
Оригинал: Programming with gtkmm 3Авторы: Murray Cumming, Bernhard Rieder, Jonathon Jongsma, Ole Laursen, Marko Anastasov, Daniel Elstner, Chris Vine, David King, Pedro Ferreira, Kjell Ahlstedt
Дата публикации: 15 Октября 2013 г.
Перевод: А.Панин
Дата перевода: 28 марта 2014 г.
23. События клавиатуры
События оконной системы X имеют некоторые отличия от других сигналов. Эти отличия описаны в разделе приложения "События оконной системы X". В данной главе мы будем использовать события клавиатуры для демонстрации того, как события оконной системы X могут быть использованы в программе.
23.1. Обзор
В любой момент, когда вы нажимаете или отпускаете клавишу, осуществляется генерация события. Вы можете установить обработчик сигналов для обработки таких событий.
Для приема событий клавиатуры в первую очередь вы должны осуществить вызов функции Gtk::Widget::add_events()
с битовой маской, указывающей на интересующие вас события, в качестве аргумента. Обработчик сигналов будет принимать аргумент, который зависит от типа события. Для событий клавиатуры это указатель на структуру GdkEventKey*
. Как указано в приложении, обработчик сигналов, связанных с событиями, возвращает логическое значение для указания на то, что сигнал обработан полностью (true
) или для разрешения распространения события (false
).
Для установления того, какая клавиша была нажата или отпущена, вы должны прочитать значение GdkEventKey::keyval
и сравнить его с константами из заголовочного файла <gdk/gdkkeysyms.h>
. Состояние клавиш модификаторов (shift, ctrl, и.т.д.) доступны в качестве битовых флагов в рамках значения GdkEventKey::state
.
bool on_key_press_or_release_event(GdkEventKey* event) { if (event->type == GDK_KEY_PRESS && event->keyval == GDK_KEY_1 && (event->state & (GDK_SHIFT_MASK | GDK_CONTROL_MASK | GDK_MOD1_MASK)) == GDK_MOD1_MASK) { handle_alt_1_press(); // GDK_MOD1_MASK обычно соответствует клавише модификатора Alt return true; } return false; } Gtk::Entry m_entry; // в объявлении класса // в конструкторе класса m_entry.signal_key_press_event().connect( sigc::ptr_fun(&on_key_press_or_release_event) ); m_entry.signal_key_release_event().connect( sigc::ptr_fun(&on_key_press_or_release_event) ); m_entry.add_events(Gdk::KEY_PRESS_MASK | Gdk::KEY_RELEASE_MASK);
23.1.1. Пример
В данном примере используются три клавиатурных сочетания: Alt+1 позволяет выбрать первую радио-кнопку, Alt+2 позволяет выбрать вторую радио-кнопку, а клавиша Esc позволяет скрыть (закрыть) окно приложения. Стандартный обработчик сигналов, связанных с событиями, перекрывается таким же образом, как описано в разделе приложения "Перекрытие стандартных обработчиков сигналов".
Рисунок 23-1: События клавиатуры - Простой пример
Файл: examplewindow.h
(Для использования совместно с gtkmm 3, а не с gtkmm 2)
Файл: examplewindow.cc
(Для использования совместно с gtkmm 3, а не с gtkmm 2)
Файл: main.cc
(Для использования совместно с gtkmm 3, а не с gtkmm 2)
23.2. Распространение событий
Под распространением событий подразумевается передача события родительскому виджету после того, как событие генерируется определенным виджетом (с последующей передачей родительскому виджету уровнем выше и.т.д.), причем в том случае, если родительский виджет имеет установленный обработчик сигналов, он будет использован.
В отличие от других типов событий, события клавиатуры в первую очередь передаются окнам верхнего уровня (на основе класса Gtk::Window
), где они подвергаются проверке на совпадение с любым из клавиатурных сочетаний, которые могут быть установлены (включая акселераторы и мнемоники, используемые для выбора элементов меню с помощью клавиатуры). После этого (если предположить, что событие не было обработано), оно передается виджету с фокусом ввода и распространение начинается с него.
Событие будет распространяться до тех пор, пока оно не достигнет виджета верхнего уровня или пока распространение события не будет остановлено вами путем возврата значения true
из функции обработчика этого события.
Учтите, что после остановки распространения события ни одна из других функций не будет вызвана (даже в том случае, если это событие от того же виджета).
23.2.1. Пример
В данном примере используются три обработчика событий, которые вызываются после стандартного обработчика событий окна на основе класса Gtk::Window
: один обработчик для виджета ввода строки на основе класса Gtk::Entry
, один обработчик для виджета сетки на основе класса Gtk::Grid
и один обработчик для виджета окна на основе класса Gtk::Window
.
В рамках класса Gtk::Window
мы также перекрываем стандартный обработчик события (on_key_release_event()
), при этом другой обработчик вызывается перед стандартным обработчиком (windowKeyReleaseBefore()
).
Целью данного примера является демонстрация шагов, которые преодолевает событие после генерации.
В момент, когда вы вводите строку в поле ввода, будет сгенерировано событие отпускания клавиши, которое в первую очередь будет передано окну верхнего уровня (на основе класса Gtk::Window
), причем один из установленных нами обработчиков событий должен быть вызван перед стандартными обработчиками (windowKeyReleaseBefore()
). После этого будет вызван стандартный обработчик событий (который мы перекрыли), а после него событие будет отправлено виджету с фокусом ввода, которым в нашем примере является виджет ввода строки и впоследствии, в зависимости от того, позволили ли мы распространение данного события, оно может достичь обработчиков событий сетки и окна. В том случае, если распространение событий разрешено, вводимая вами строка будет отображаться с помощью виджета вывода строки, расположенного над виджетом ввода строки.
Рисунок 23-2: События клавиатуры - Распространение событий
Файл: examplewindow.h
(Для использования совместно с gtkmm 3, а не с gtkmm 2)
Файл: examplewindow.cc
(Для использования совместно с gtkmm 3, а не с gtkmm 2)
Файл: main.cc
(Для использования совместно с gtkmm 3, а не с gtkmm 2)
Следующий раздел : Функции с временем ожидания, мониторинг операций ввода/вывода и функции для периодов бездействия.