Компания ALT Linux
Опубликован: 07.03.2015 | Доступ: свободный | Студентов: 2136 / 487 | Длительность: 24:14:00
Лекция 14:

Собственные классы в Qt. Создание элементов графического интерфейса

14.3 События (Events). Обработка событий (Event handling)

В Qt существует механизм, который позволяет обрабатывать различные события, происходящие в системе и в самой программе. Визуальные элементы пользовательского интерфейса получают события от устройств ввода информации, которыми управляет пользователь: мышки, клавиатуры и т.п.. Также события могут поступать от объектов изнутри приложения. Таким образом бывают:

  • события, возникшие спонтанно и поступающие от оконной системы, такие как нажатие клавиш, движения мышкой, манипуляции с окном программы (spontaneous events);
  • события, отправленные изнутри программы, созданные объектами в программе и направленные в цикл обработки событий (posted events) или напрямую к другому объекту (sent events).

Спонтанные события и большинство внутренних событий поступают в цикл обработки событий (event loop). Этот цикл последовательно рассматривает каждое из событий и отправляет на обработку конкретному объекту. Каждый объект в свою очередь имеет возможность обрабатывать событие, которое поступает к нему.

Каждое событие в Qt существует в виде объекта, унаследованного от QEvent. Когда событие поступает на обработку, то для объекта-обработчика выполняется виртуальный метод QObject::event(). Этот метод обычно вызывает другой метод-обработчик события, который для большинства событий является отдельным. Это необходимо для удобства и гибкости, поскольку таким образом есть возможность запрограммировать обработку конкретного класса событий в отдельном методе. Почти все основные типы событий реализованы в виде отдельного класса. Например, события для движений и нажатий клавиш мышки имеют класс QMouseEvent, события для нажатий клавиш клавиатуры имеют класс QKeyEvent и т. п. В табл. 14.1 приведены события, которые часто необходимо обрабатывать при разработке программ с графическим интерфейсом.

Таблица 14.1. Часто употребляемые классы событий и их обработчики
Название класса события Описание Обработчик события
QMouseEvent Событие для движений мышкой и нажатия клавиш мышки. Посылается виджетам. Выполняется только при нажатии клавиши мышки. Для того, чтобы виджет постоянно отслеживал этот тип событий, необходимо передать true в метод виджета setMouseTracking(). клавиша мышки нажата
QWidget::mousePressEvent()
клавишу мышки отпустили
QWidget::mouseReleaseEvent()
клавишу мышки нажали два раза
QWidget::mouseDoubleClickEvent()
курсор мышки изменил позицию
QWidget::mouseMoveEvent()
QKeyEvent Событие для нажатия клавиш клавиатуры клавиша нажата
QWidget::keyPressEvent()
клавишу отпустили
QWidget::keyReleaseEvent()
QResizeEvent Сообщает об изменении размера виджета (изменение уже произошло)
QWidget::resizeEvent()
QPaintEvent Сообщает о необходимости перерисовки виджета
QWidget::paintEvent()
QTimerEvent Посылается через заданные интервалы времени объектом, который запустил один или несколько таймеров с помощью метода QObject::startTimer(). Каждый таймер имеет уникальный идентификатор, который возвращает метод QObject::startTimer() при создании нового таймера. Таймер можно остановить с помощью вызова метода QObject::killTimer().
QObject::timerEvent()
QCloseEvent Посылается окну, которое пользователь пытается закрыть. Позволяет контролировать закрыто окно после обработки события или нет.
QWidget::closeEvent()

Таким образом, для того, чтобы выполнить обработку события, необходимо переопределить нужный обработчик события, выполнить необходимые для обработки действия и, если необходимо, сохранить стандартное поведение для обработчика — вызвать обработчика события из родительского класса. Теперь вернёмся к одному из предыдущих примеров — собственному виджету для поля ввода с пиктограммой. После изменения размера окна (и поля ввода, которое было размещено в компоновке), нам необходимо обновить позицию значка для того, чтобы она всегда находилась в правом конце поля ввода. Для этого мы можем переопределить обработчик события QResizeEvent для класса IconizedLineEdit:

//Событие изменения размера виджета
void IconizedLineEdit::resizeEvent ( QRes izeEvent *pEvent )
{
	//Если изменение размера состоялось, обновить позицию и размер пиктограммы
	updateIconPositionAndsize ( );
	QWidget::resizeEvent ( pEvent );
}

Для обновления позиции пиктограммы достаточно ещё раз вызвать метод IconizedLineEdit::updateIconPositionAndSize(). После изменения размера поля ввода позиция пиктограммы будет автоматически обновлена.

Сергей Радыгин
Сергей Радыгин

Символы кириллицы выводит некорректно. Как сделать чтобы выводился читабельный текст на русском языке?

Тип приложения - не Qt,

Qt Creator 4.5.0 основан на Qt 5.10.0. Win7.

 

Юрий Герко
Юрий Герко

Кому удалось собрать пример из раздела 13.2 Компоновка (Layouts)? Если создавать проект по изложенному алгоритму, автоматически не создается  файл mainwindow.cpp. Если создавать этот файл вручную и добавлять в проект, сборка не получается - компилятор сообщает об отсутствии класса MainWindow. Как правильно выполнить пример?