在QT中,鼠标事件包含:鼠标按键按下,鼠标按键释放,鼠标双击事件,鼠标移动事件。
分别由下面的event handler(事件处理器,实际上就是一些可override的函数)来处理:
virtual void mousePressEvent(QMouseEvent *event);
virtual void mouseReleaseEvent(QMouseEvent *event);
virtual void mouseDoubleClickEvent(QMouseEvent *event);
virtual void mouseMoveEvent(QMouseEvent *event);
鼠标事件属于冒泡事件,鼠标事件会一直随着其父链一直路由下去,直到有其祖先所在的widget接受它,或者有事件过滤器消耗它。
注意:如果鼠标事件被路由到包含Qt:: WA_NoMousePropagation窗口属性(即该属性设置为true)的窗口小部件,该鼠标事件不会进一步沿着父控件链路由。如下代码:
#include "MainWindow.h"
#include<QMouseEvent>
#include <QPainter>
#include <QDebug>
#include <QVBoxLayout>
#include <QPushButton>
#include <QLabel>
MainWindow::MainWindow(QWidget* parent)
: QMainWindow(parent)
{
ui.setupUi(this);
this->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
this->setFixedSize(500, 500);
QWidget* wg1 = new QWidget(this);
wg1->setFixedSize(300, 300);
wg1->setStyleSheet("background-color:black;");
QWidget* wg2 = new QWidget(wg1);
wg2->setFixedSize(100, 100);
wg2->setStyleSheet("background-color:red;");
QHBoxLayout* m_layout = new QHBoxLayout;
wg2->setLayout(m_layout);
QPushButton* m_btn1 = new QPushButton(wg2);
m_layout->addWidget(m_btn1);
m_btn1->setText("--btn1--");
// 当属性为false时,下面这句可以屏蔽,因为该属性默认就是flase的
m_btn1->setAttribute(Qt::WA_NoMousePropagation, false);
QLabel* m_label = new QLabel(wg2);
m_label->setFixedSize(20, 100);
m_layout->addWidget(m_label);
m_label->setStyleSheet("background-color:pink");
// 按钮鼠标跟踪事件要设置为true,否则鼠标在按钮上移动不会激发mouseMoveEvent
m_btn1->setMouseTracking(true);
setMouseTracking(true);
wg1->setMouseTracking(true);
wg2->setMouseTracking(true);
}
void MainWindow::mouseMoveEvent(QMouseEvent* event)
{
QPoint p_ab = event->globalPos();
QPoint p_re = event->pos();
QString str;
str = QString("%1 , %2").arg(p_ab.x()).arg(p_ab.y());
qInfo() << str;
}
运行结果如下:
可以看到,当按钮的Qt::WA_NoMousePropagation属性设置为false时,鼠标在按钮上的移动事件传递到MainWindow中了。当改为下面代码
m_btn1->setAttribute(Qt::WA_NoMousePropagation, true);
则MainWindow无法收到鼠标在按钮上的移动事件