На этом шаге рассмотрим переопределение метода event().
Все возникающие в системе события направляются в очередь, из которой они извлекаются циклом событий, находящимся в методе exec() объекта приложения QCoreApplication или QApplication. Объект класса QApplication посылает события тем виджетам, которым они предназначены. Все объекты событий поступают в метод event(), в котором определяется их тип и осуществляется вызов специализированных методов обработки, предназначенных для этих событий, например вызов метода mousePressEvent() при нажатии кнопки мыши. Это проиллюстрировано на рис. 1.
Рис.1. Схема доставки и обработки событий
Метод event(), как и все остальные специализированные методы обработки событий, — виртуальный. Его можно переопределить, но это следует делать только в тех случаях, когда есть острая необходимость, т. к. такое переопределение может изрядно усложнить исходный код всей программы. Если все события будут обрабатываться только одним методом event(), то это может привести к появлению громоздкого метода, содержащего несколько тысяч строк для обработки всевозможных событий.
Поэтому, если есть возможность, лучше всего перезаписывать соответствующие специализированные методы для обработки событий. Обработку событий в методе event() лучше всего применять для тех типов событий, для которых не существует специализированных методов обработки.
В метод event() передается указатель на объект типа QEvent. Все события унаследованы от класса QEvent, который содержит атрибут, представляющий собой целочисленный идентификатор типа события, и с его помощью можно всегда привести указатель на объект класса QEvent к нужному типу.
В методе event() программа должна определить, какое событие произошло. Для облегчения этой задачи существует метод type(). Возвращаемое им значение можно сравнить с предопределенной константой (см. табл. 1, шаг 127), что даст возможность привести это событие к правильному типу.
Перезапись метода event() для класса, унаследованного, например, от класса QWidget, может выглядеть следующим образом:
bool MyClass::event(QEvent* pe) { if (pe->type() == QEvent::KeyPress) { QKeyEvent* pKeyEvent = static_cast<QKeyEvent*>(pe); if (pKeyEvent->key() == Qt::Key_Tab) { // Выполнить какие-либо действия return true; } } if (pe->type() == QEvent::Hide) { // Выполнить какие-либо действия return true; } return QWidget::event(pe); }
Метод возвращает true в том случае, если событие было обработано и не требует передачи дальше. После этого событие удаляется из очереди событий. При возвращении false событие будет передано дальше — виджету-предку. Если ни один из предков не сможет обработать событие, то оно будет просто проигнорировано и удалено из очереди событий.
На следующем шаге рассмотрим cохранение работоспособности приложения.