Чтение онлайн

на главную - закладки

Жанры

QT 4: программирование GUI на С++

Саммерфилд Марк

Шрифт:

Установка фильтров событий

Одним из действительно эффективных средств в модели событий 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.

Поделиться:
Популярные книги

Жена со скидкой, или Случайный брак

Ардова Алиса
Любовные романы:
любовно-фантастические романы
8.15
рейтинг книги
Жена со скидкой, или Случайный брак

Осколки маски

Метельский Николай Александрович
7. Унесенный ветром
Фантастика:
боевая фантастика
альтернативная история
6.71
рейтинг книги
Осколки маски

Мастер 4

Чащин Валерий
4. Мастер
Фантастика:
героическая фантастика
боевая фантастика
попаданцы
5.00
рейтинг книги
Мастер 4

Горизонт Вечности

Вайс Александр
11. Фронтир
Фантастика:
боевая фантастика
космическая фантастика
космоопера
5.00
рейтинг книги
Горизонт Вечности

Потомок бога 3

Решетов Евгений Валерьевич
3. Локки
Фантастика:
аниме
фэнтези
5.00
рейтинг книги
Потомок бога 3

Запечатанный во тьме. Том 1. Тысячи лет кача

NikL
1. Хроники Арнея
Фантастика:
уся
эпическая фантастика
фэнтези
5.00
рейтинг книги
Запечатанный во тьме. Том 1. Тысячи лет кача

Путь

Yagger Егор
Фантастика:
космическая фантастика
4.25
рейтинг книги
Путь

Ученик. Книга третья

Первухин Андрей Евгеньевич
3. Ученик
Фантастика:
фэнтези
7.64
рейтинг книги
Ученик. Книга третья

Хозяин Теней 5

Петров Максим Николаевич
5. Безбожник
Фантастика:
аниме
фэнтези
фантастика: прочее
попаданцы
5.00
рейтинг книги
Хозяин Теней 5

Я не царь. Книга XXIV

Дрейк Сириус
24. Дорогой барон!
Фантастика:
юмористическое фэнтези
аниме
попаданцы
5.00
рейтинг книги
Я не царь. Книга XXIV

Сильнейший Столп Империи. Книга 5

Ермоленков Алексей
5. Сильнейший Столп Империи
Фантастика:
аниме
фэнтези
фантастика: прочее
попаданцы
5.00
рейтинг книги
Сильнейший Столп Империи. Книга 5

Кодекс Охотника. Книга XXII

Винокуров Юрий
22. Кодекс Охотника
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Кодекс Охотника. Книга XXII

Чевенгур

Платонов Андрей Платонович
Проза:
советская классическая проза
6.75
рейтинг книги
Чевенгур

Новые горизонты

Лисина Александра
5. Гибрид
Фантастика:
попаданцы
технофэнтези
аниме
сказочная фантастика
фэнтези
5.00
рейтинг книги
Новые горизонты