Шаг 111.
Библиотека Qt.
События

    На этом шаге рассмотрим некоторые общие сведения о событиях.

    Обработка событий лежит в основе работы каждого приложения, имеющего пользовательский интерфейс. Событие можно охарактеризовать как механизм оповещения приложения о каком-либо происшествии. Например, нажатие пользователем кнопки мыши или клавиши клавиатуры приведет к созданию события мыши или клавиатуры, событие будет создаваться и при необходимости перерисовки содержимого окна и т. д. Очевидно, что основная масса событий тесно связана с действиями, предпринимаемыми пользователем. Но есть и события, создаваемые самой операционной системой, например событие таймера. Все события помещаются в соответствующую очередь для их дальнейшей обработки.

    Но ведь если "что-то происходит", то высылаются сигналы. Зачем же тогда нужны события?

    Механизм сигналов и слотов, по сравнению с событиями, представляет собой механизм более высокого уровня, предназначенный для связи объектов. Хотя и то и другое является уведомлением о происходящем.

    Например, нажатие кнопки приводит к оповещению о происходящем всех подключенных к сигналу объектов. События оповещают объекты о действиях пользователя общего и детального характера (например, перемещение указателя мыши или нажатие какой-либо клавиши клавиатуры). Другими словами, воспользовавшись стандартными сигналами, вы можете сделать заключение о том, что кнопка была нажата, а узнать координаты указателя мыши в момент нажатия не представляется возможным. Для получения подобного рода информации понадобятся объекты событий, часто содержащие дополнительную информацию, которой может воспользоваться объект, получающий события. В частности, в объекте события мыши QMouseEvent передаются координаты и код нажатой кнопки.

    Использование событий особенно интересно при создании собственных виджетов, поскольку часто сигналы высылаются из методов обработки событий. Например, при щелчке мыши на виджете можно из метода обработки события mousePressEvent() выслать сигнал clicked().

    Следует учитывать, что в Qt все методы обработки событий определены как virtual protected. Поэтому при переопределении этих методов в унаследованных классах желательно определять их как protected.

    Есть еще одно отличие сигналов от событий — события могут быть обработаны лишь одним методом, а сигналы могут обрабатываться неограниченным количеством соединенных с ними слотов. И еще, сигналы могут базироваться на событиях, т. е. высылаться из методов событий, но высылку событий из сигналов просто даже невозможно себе представить.

    Qt предоставляет целый ряд классов для различного рода событий: клавиатуры, мыши, таймера и др. На рис. 1 представлена иерархия классов событий Qt.


Рис.1. Иерархия классов событий

    Как видно из рис. 1, класс QEvent является базовым для всех категорий событий. Его объекты содержат информацию о типе произошедшего события. А для каждого типа события имеется целочисленный идентификатор, который устанавливается в конструкторе QEvent и может быть получен при помощи метода QEvent::type().

    Класс события QEvent содержит методы accept() и ignore(), с помощью которых устанавливается или сбрасывается специальный флаг, регулирующий дальнейшую обработку события предком объекта. Если был вызван метод ignore(), то при возвращении из метода обработки события событие будет передано дальше на обработку объекту-предку.

    Класс QInputEvent является базовым для событий, связанных с пользовательским вводом (рис. 1). Этот класс реализует всего лишь один метод modifiers(). С его помощью все унаследованные от него классы могут получать состояние клавиш-модификаторов <Ctrl>, <Shift> и <Alt>, которые могут быть нажаты в момент наступления события. Некоторые их значения указаны в табл. 1.

Таблица 1. Некоторые значения модификаторов пространства имен Qt
Константа
Значение(HEX)
Описание
NoModifier
0 Клавиши модификаторов не нажаты
ShiftModifier
2000000 Нажата клавиша <Shift>
ControlModifier
4000000 Нажата клавиша <Ctrl>
AltModifier
8000000 Нажата клавиша <Alt>

    Обработка событий начинается с момента вызова в вашей основной программе метода QCoreApplication::exec(). События доставляются всем объектам, созданным от классов, которые унаследованы от класса QObject. Некоторые события могут быть доставлены сразу, а некоторые попадают в очередь и могут быть обработаны только при возвращении управления циклу обработки события QCoreApplication::exec(). Qt использует специальные механизмы для оптимизации некоторых типов событий. Так, например, серия событий перерисовки QPaintEvent в целях увеличения производительности может быть "упакована" (объединена) в одно событие, с регионом рисования, составленным из регионов всех находящихся в очереди событий рисования. Тем самым метод обработки события рисования (paintEvent()) будет вызван только один раз.

    На следующем шаге рассмотрим переопределение специализированных методов обработки событий.




Предыдущий шаг Содержание Следующий шаг