На этом шаге мы рассмотрим реализацию фильтрации событий.
События можно перехватывать еще до того, как они будут переданы компоненту. Для этого необходимо создать класс, который является наследником класса QObject, и переопределить в нем метод eventFilter(seif, <Объект>, <event>). Через параметр <Объект> доступна ссылка на компонент, а через параметр <event> - на объект с дополнительной информацией о событии. Этот объект отличается для разных типов событий - так, для события MouseButtonPress объект будет экземпляром класса QMouseEvent, а для события KeyPress - экземпляром класса QKeyEvent. Из метода eventFilter() следует вернуть значение True, если событие не должно быть передано дальше, и False - в противном случае. Вот пример такого класса-фильтра, перехватывающего нажатие клавиши В:
class MyFilter (QtCore.QObject): def __init__(self, parent = None): QtCore.QObject.__init__(self, parent) def eventFilter (self, obj , e): if e.type() == QtCore.QEvent.KeyPress: if e.key() == QtCore.Qt.Key_B: print("Событие от клавиши <В> не дойдет до компонента") return True return QtCore.QObject.eventFilter(self, obj, e)
Далее следует создать экземпляр этого класса, передав в конструктор ссылку на компонент, а затем вызвать у того же компонента метод installEventFilter(), передав в качестве единственного параметра ссылку на объект фильтра. Пример установки фильтра для надписи:
self.label.installEventFilter (MyFilter (self.label))
Метод installEventFilter() можно вызвать несколько раз, передавая ссылку на разные объекты фильтров. В этом случае первым будет вызван фильтр, который был добавлен последним. Кроме того, один фильтр можно установить сразу в нескольких компонентах. Ссылка на компонент, который является источником события, доступна через второй параметр метода eventFilter().
Удалить фильтр позволяет метод removeEventFilter(<Фильтр>), вызываемый у компонента, для которого был назначен этот фильтр. Если таковой не был установлен, при вызове метода ничего не произойдет.
На следующем шаге мы рассмотрим искусственные события.