На этом шаге рассмотрим класс QMouseEvent.
Мышь дает возможность пользователю указывать на объекты, находящиеся на экране компьютера, и с ее помощью можно проводить различные манипуляции над объектами, которые невозможно или неудобно выполнять с помощью клавиатуры.
Реализация событий мыши сложнее других, поскольку программа должна определять, какая кнопка нажата, удерживается она или нет, был ли выполнен двойной щелчок и какие клавиши клавиатуры были нажаты в момент возникновения события.
Объект класса QMouseEvent содержит информацию о событии, вызванном действием мыши, и хранит в себе информацию о позиции указателя мыши в момент вызова события, статус кнопок мыши и даже некоторых клавиш клавиатуры.
Этот объект передается в методы mousePressEvent(), mouseMoveEvent(), mouseReleaseEvent() и mouseDoubleClickEvent().
Метод mousePressEvent() вызывается тогда, когда произошло нажатие на одну из кнопок мыши в области виджета. Если, нажав кнопку мыши, и не отпуская ее, переместить указатель мыши за пределы виджета, то он будет получать события мыши, пока кнопка не будет отпущена.
При движении мыши будет вызываться метод mouseMoveEvent(), а при отпускании кнопки произойдет вызов метода mouseReleaseEvent().
По умолчанию метод mouseMoveEvent() вызывается при перемещении указателя мыши, только если одна из ее кнопок нажата. Это позволяет не создавать лишних событий во время простого перемещения указателя. Если же необходимо отслеживать все перемещения указателя мыши, то нужно воспользоваться методом setMouseTracking() класса QWidget, передав ему параметр true.
Метод mouseDoubleClickEvent() вызывается при двойном щелчке кнопкой мыши в области виджета.
Для определения местоположения указателя мыши в момент возникновения события можно воспользоваться методами globalX(), globalY(), x() и y(), которые возвращают целые значения. Также можно воспользоваться методами pos() или globalPos(). Метод pos() класса QMouseEvent возвращает позицию указателя мыши в момент наступления события относительно левого верхнего угла виджета. Если нужна абсолютная позиция (относительно левого верхнего угла экрана), то ее получают с помощью метода globalPos().
Вызвав метод button(), можно узнать, какая из кнопок мыши была нажата в момент наступления события (табл. 1). Метод buttons() возвращает битовую комбинацию из приведенных в табл. 1 значений. Как видно из этой таблицы, значения не пересекаются, поэтому можно применять операцию | (ИЛИ) для их объединения.
Кнопки мыши не нажаты | ||
Нажата левая кнопка мыши | ||
Нажата правая кнопка мыши | ||
Нажата средняя кнопка мыши |
Если необходимо узнать, были ли в момент возникновения события мыши нажаты клавиши-модификаторы Ctrl, Shift и/или Alt, то это можно проверить с помощью метода modifiers(), реализованного в базовом классе QInputEvent (см. рис. 1 и табл. 1 шага 111).
При вызове mouseDoubleClickEvent() метод mousePressEvent() вызывается дважды, т. к. двойной щелчок обрабатывается как два простых нажатия. По умолчанию интервал двойного щелчка составляет 400 мс, а для изменения этого интервала нужно вызвать метод setDoubleClickInterval() класса QApplication.
На рис. 1 показана программа, демонстрирующая обработку событий мыши. На рисунке мышь находится в состоянии перемещения указателя с нажатыми левой и правой кнопками и с нажатыми клавишами Ctrl, Alt и Shift.
Рис.1. Виджет, получающий события мыши
Приведем краткое описание кода приложения. Начнем с заголовочного файла:
class ME:public QLabel { public: ME(QWidget *pwgt=0); protected: //методы для обработки событий мыши: //1) для нажатия на кнопку мыши virtual void mousePressEvent (QMouseEvent* pe); //2) для отпускания кнопки мыши virtual void mouseReleaseEvent(QMouseEvent* pe); //3) для перемещения мыши virtual void mouseMoveEvent (QMouseEvent* pe); //4) выводит информацию о состоянии события мыши void dumpEvent (QMouseEvent* pe, const QString& strMessage); //5) предоставляет информацию о клавишах-модификаторах QString modifiersInfo (QMouseEvent* pe); //6) предоставляет информацию о кнопках мыши QString buttonsInfo (QMouseEvent* pe); };
Рассмотрим реаоизацию этих событий:
ME::ME(QWidget* pwgt /*= 0*/) : QLabel(pwgt) { //вызов метода setAlignment() с параметром AlignCenter //выполняет центровку всей выводимой нами информации setAlignment(Qt::AlignCenter); //вывод текста setText("Нажмите кнопку мыши"); } //В методах mousePressEvent(), mouseReleaseEvent() и mouseMoveEvent(), //отслеживающих события мыши, вызывается метод — dumpEvent(), //в который передаются указатель на объект события и строка, //информирующая о методе обработки этого события /*virtual*/void ME::mousePressEvent(QMouseEvent* pe) { dumpEvent(pe, "Нажаты кнопки мыши"); } /*virtual*/void ME::mouseReleaseEvent(QMouseEvent* pe) { dumpEvent(pe, "Кнопка мыши отпущена"); } /*virtual*/ void ME::mouseMoveEvent(QMouseEvent* pe) { dumpEvent(pe, "Указатель мыши перемещается"); } //Вся информация собирается в методе dumpEvent() в одну строку //и выводится при помощи метода setText() void ME::dumpEvent(QMouseEvent* pe, const QString& strMsg) { setText(strMsg + "\n buttons()=" + buttonsInfo(pe) + "\n x()=" + QString::number(pe->x()) + "\n y()=" + QString::number(pe->y()) + "\n globalX()=" + QString::number(pe->globalX()) + "\n globalY()=" + QString::number(pe->globalY()) + "\n modifiers()=" + modifiersInfo(pe) ); } //Метод modifiersInfo() предоставляет информацию о клавишах-модификаторах //в виде строки, нажатие которых проверяется вы-зовом метода modifiers() QString ME::modifiersInfo(QMouseEvent* pe) { QString strModifiers; if(pe->modifiers() & Qt::ShiftModifier) { strModifiers += "Shift"; } if(pe->modifiers() & Qt::ControlModifier) { strModifiers += "Control"; } if(pe->modifiers() & Qt::AltModifier) { strModifiers += "Alt"; } return strModifiers; } //Информацию о нажатых кнопках мыши предоставляет метод buttonsInfo() QString ME::buttonsInfo(QMouseEvent* pe) { QString strButtons; if(pe->buttons() & Qt::LeftButton) { strButtons += "Left "; } if(pe->buttons() & Qt::RightButton) { strButtons += "Right "; } if(pe->buttons() & Qt::MidButton) { strButtons += "Middle"; } return strButtons; }
Файлы приложения можно взять здесь.
На следующем шаге рассмотрим класс QWheelEvent.