Установка фильтров событий
Установка фильтров событий
Одним из действительно эффективных средств в модели событий Qt является возможность с помощью некоторого экземпляра объекта QObject контролировать события другого экземпляра объекта QObject еще до того, как они дойдут до последнего.
Предположим, что наш виджет CustomerInfoDialog состоит из нескольких редакторов строк QLineEdit и мы хотим использовать клавишу Space (пробел) для передачи фокуса следующему QLineEdit. Такой необычный режим работы может оказаться полезным для разработки, предназначенной для собственных нужд, и когда пользователи имеют навык работы в таком режиме. Простое решение заключается в создании подкласса QLineEdit и переопределении фyнкции keyPressEvent() для вызова focusNextChild(), и оно выглядит следующим образом:
01 void MyLineEdit::keyPressEvent(QKeyEvent *event)
02 {
03 if (event->key()== Qt::Key_Space) {
04 focusNextChild();
05 } else {
06 QLineEdit::keyPressEvent(event);
07 }
08 }
Этот подход имеет один основной недостаток: если мы используем в форме несколько различных видов виджетов (например, QComboBox и QSpinBox), мы должны также создать их подклассы для обеспечения единообразного поведения. Лучшее решение заключается в перехвате виджетом CustomerInfoDialog событий нажатия клавиш клавиатуры своих дочерних виджетов и в обеспечении необходимого поведения в его программном коде. Это можно сделать при помощи фильтров событий. Настройка фильтров событий сострит из двух этапов:
1. Зарегистрируйте объект—перехватчик с целевым объектом посредством вызова функции installEventFilter() для целевого объекта.
2. Выполните обработку событий целевого объекта в функции eventFilter() перехватчика.
Регистрацию объекта контроля удобно выполнять в конструкторе CustomerInfoDialog:
01 CustomerInfoDialog::CustomerInfoDialog(QWidget *parent)
02 : QDialog(parent)
03 {
04 firstNameEdit->installEventFilter(this);
05 lastNameEdit->installEventFilter(this);
06 cityEdit->installEventFilter(this);
07 phoneNumberEdit->installEvehtFilter(this);
08 }
После регистрации фильтра события те из них, которые посылаются виджетам firstNameEdit, lastNameEdit, cityEdit и phoneNumberEdit, сначала будут переданы функции eventFilter() виджета CustomerInfoDialog и лишь затем дойдут по своему прямому назначению. (Если для одного объекта установлено несколько фильтров событий, они вызываются по очереди, начиная с установленного последним и последовательно возвращаясь к первому.)
Ниже приводится функция eventFilter(), которая перехватывает события:
01 bool CustomerInfoDialog::eventFilter(QObject *target, QEvent *event)
02 {
03 if (target == firstNameEdit || target == lastNameEdit
04 || target == cityEdit || target == phoneNumberEdit) {
05 if (event->type() == QEvent::KeyPress) {
06 QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
07 if (keyEvent->key() == Qt::Key_Space) {
08 focusNextChild();
09 return true;
10 }
11 }
12 }
13 return QDialog::eventFilter(target, event);
14 }
Во-первых, мы проверяем, является ли целевой виджет строкой редактирования QLineEdit. Если событие вызвано нажатием клавиши клавиатуры, мы преобразуем его тип в QKeyEvent и проверяем, какая клавиша нажата. Если нажата клавиша пробела Space, мы вызываем функрию focusNextChild() для перехода фокуса на следующий виджет в фокусной цепочке и возвращаем true для уведомления Qt о завершении нами обработки события. Если бы мы вернули false, Qt отослала бы событие по его прямому назначению,что привело бы к вставке лишнего пробела в строку редактирования QLineEdit.
Если целевым виджетом не является QLineEdit или если событие не вызвано нажатием клавиши Space, мы передаем управление функции базового класса eventFilter(). Целевым виджетом мог бы быть также некоторый виджет, базовый класс которого QDialog осуществляет контроль. (В Qt 4.1 этого не происходит с QDialog. Однако другие классы виджетов в Qt, например QScrollArea, контролируют по различным причинам некоторые свои дочерние виджеты.)
Qt предусматривает пять уровней обработки и фильтрации событий:
1. Мы можем переопределять конкретный обработчик событий.
Переопределение таких обработчиков событий, как mousePressEvent(), keyPressEvent() и paintEvent(), представляет собой очень распространенный способ обработки событий. Мы уже видели много примеров такой обработки.
2. Мы можем переопределять функцию QObject::event().
Путем переопределения функции event() мы можем обрабатывать события до того, как они дойдут до обработчиков соответствующих событий. Этот подход очень хорош для изменения принятого по умолчанию поведения клавиши табуляции Tab, что было показано ранее. Он также используется для обработки редких событий, для которых не предусмотрены отдельные обработчики событий (например, QEvent::HoverEnter). При переопределении функции event() нам необходимо вызывать функцию базового класса event() для обработки тех событий, которые мы сами не обрабатываем.
3. Мы можем устанавливать фильтр событий для отдельного объекта QObject.
После регистрации объекта с помощью функции installEventFilter() все события целевого объекта сначала передаются функции контролирующего объекта eventFilter(). Если для одного объекта установлено несколько фильтров, они действуют поочередно, начиная с того, который установлен последним, и кончая тем, который установлен первым.
4. Мы можем устанавливать фильтр событий для объекта QApplication.
После регистрации фильтра для qApp (уникальный объект типа QApplication) каждое событие каждого объекта приложения передается функции eventFilter() до его передачи любым другим фильтрам событий. Этот подход очень удобен для отладки. Он может также использоваться для обработки событий мышки, посылаемых для отключенных виджетов, которые обычно отклоняются QApplication.
5. Мы можем создать подкласс QApplication и переопределить функцию notify().
Qt вызывает QApplication::notify() для генерации события. Переопределение этой функции представляет собой единственный способ получения доступа ко всем событиям до того, как ими займутся фильтры событий. Пользоваться фильтрами событий, как правило, удобнее, поскольку параллельно может существовать любое количество фильтров событий и только одна функция notify().
События многих типов, в том числе события мышки и клавиатуры, могут передаваться дальше по системе объектов приложения. Если событие не было обработано ни на пути к целевому объекту, ни самим целевым объектом, процесс обработки события повторяется, но теперь в качестве нового целевого объекта используется родительский объект. Этот процесс продолжается, управление передается от одного родительского объекта к другому до тех пор, пока либо событие не будет обработано, либо не будет достигнут объект самого верхнего уровня.
Рис. 7.2. Передача события в диалоговом окне.
На рис. 7.2 показано, как событие нажатия клавиши пересылается в диалоговом окне от дочернего объекта к родительскому. Когда пользователь нажимает клавишу на клавиатуре, сначала событие передается виджету, на котором установлен фокус — в данном случае это расположенный в нижнем правом углу флажок QCheckBox. Если QCheckBox не обрабатывает это событие, Qt передает его объекту QGroupBox и в конце концов объекту QDialog.
Более 800 000 книг и аудиокниг! 📚
Получи 2 месяца Литрес Подписки в подарок и наслаждайся неограниченным чтением
ПОЛУЧИТЬ ПОДАРОКЧитайте также
Выражения фильтров и их значения
Выражения фильтров и их значения Параметр выражение_фильтра в операторе except вычисляется сразу же после того, как возникает исключение. В качестве выражения может выступать литеральная константа, вызов функции фильтра (filter function) или условное выражение. В любом случае
Использование фильтров Procmail
Использование фильтров Procmail Серверы SMTP, описанные в данной главе, могут обрабатывать письма, отправленные с внешних компьютеров. До сих пор мы не рассматривали вопрос о том, что происходит с письмом после того, как оно принимается сервером. В простейшем случае почтовый
2.2.4. Настройка фильтров
2.2.4. Настройка фильтров Фильтры можно разделить на три типа:? "черные" списки;? "белые" списки;? морфологические фильтры.Черные и белые списки содержат почтовые адреса, которые вы заносите в них сами. Работают они, как понятно из их названия, с противоположным эффектом.
Урок 17. Работа 3D-фильтров
Урок 17. Работа 3D-фильтров Фильтр 3D TransformДанный фильтр появился в ранних версиях. С его помошью можно создавать трехмерные объекты на любой поверхности. К сожалению, в новой версии Photoshop он отсутствует в стандартном наборе. Тем не менее фильтр не пропал бесследно. Он
Урок 24. Галерея фильтров
Урок 24. Галерея фильтров Фильтры Grain, Neon Glow, Glowing Edges, Motion BlurШаг 1Создайте новое изображение произвольного размера, например 1024x768 — стандартный размер обоев на рабочем столе. Рис. 24.1. Галерея фильтров с примененным фильтром GrainИзображение должно быть белым. Обязательно
Урок 15 Царство фильтров
Урок 15 Царство фильтров Вы, наверное, удивитесь, но, помимо многочисленных инструментов рисования и редактирования, рассмотренных нами в предыдущих уроках, Photoshop вооружен огромным количеством дополнительных встроенных программ (плагинов), каждая из которых выполняет
Глава 15 Использование фильтров
Глава 15 Использование фильтров Цифровым фотографиям и сканированным изображениям нередко присущи такие недостатки и искажения, как недостаточная или избыточная резкость и наличие посторонних шумов.Данная глава будет посвящена тому, как избавиться от этих недостатков
Обзор групп фильтров
Обзор групп фильтров В Photoshop просто огромное количество фильтров, исчисляемое десятками. Поэтому нет ничего удивительного в том, что разработчики разделили их на категории. Благодаря этому найти нужный фильтр не составляет труда. Если же вы не знаете, какой фильтр вам
Написание фильтров BLOB
Написание фильтров BLOB Написание фильтров BLOB требует точно таких же усилий по управлению памятью и потоками, а также того же порядка действий, что и другие внешние функции, а именно:1. Напишите фильтры и скомпилируйте их в объектные коды.2. Создайте совместно используемую
Инструменты для написания фильтров
Инструменты для написания фильтров API Firebird содержит группу макрофункций, начинающихся с isc_biob_fiiter_, которые являются "инструментом программиста" для написания фильтров BLOB. Документы API Guide и Embedded SQL Guide из набора документов Borland по InterBase версии 6 бета имеют разделы по
Создание фильтров
Создание фильтров Для создания фильтров нам понадобится "универсальная" панель Properties. Только в этом случае нам понадобится переключиться на вкладку Filters этой панели (рис. 9.1). Также можно включить пункт-переключатель Filters подменю Properties меню Window. В левой части панели Properties
Использование фильтров
Использование фильтров Вы можете встретиться с задачей отбора записей в объемном списке данных, что занимает продолжительное время. Для этого проще всего использовать встроенные возможности фильтрации данных. Excel 2007 обладает простыми и удобными средствами установки
Использование фильтров
Использование фильтров С помощью фильтра можно отбирать для отображения в таблице только записи, которые отвечают определенным критериям. Для установки фильтров в Access 2007 существует несколько способов.Рассмотрим их.Фильтр по выделенному значению. Этот способ позволяет