今天要探讨一个非常非常蛋疼的问题,就是关于QMainWindow令人头疼的鼠标事件,如果从解决问题的角度来说,今天要探讨的是QMainWindow的对MouseMove监视的解决方案。
问题:在QMainWindow使用鼠标移动监测事件时,还是需要按键后移动才能实时监控鼠标当前坐标,而不能直接监视移动的鼠标,换句话说就是移动鼠标,程序并没有进入MouseMoveEvent中!
具体情况:设置两个标签,实时监控移动中的鼠标位置坐标
void Similary::mouseMoveEvent(QMouseEvent* e)
{
QString str1 = QString::number(e->x());
QString str2 = QString::number(e->y());
imgLab1->setText(str1);
imgLab2->setText(str2);
}
结果:鼠标要点击后按住按键不放并且移动才能显示实时位置坐标。就算是setmousetracking(1),亲测也是不管用的。
经过找寻答案,我发现了又是因为QMainWindow的独特之处!如果使用UI(QT设计师)添加控件,那么在QMainWindow窗体上会自动添加一个centralWidget层,而我们使用的是QMAinWindow的鼠标移动监测事件,centralWidget将QMainWindow遮挡住了,所以鼠标移动也无法进入mouseMoveEvent。那你会说,好吧,那我就用代码就好了,不用UI设计!我们上回说道,如果QMainWindow要添加布局管理器,是避免不了使用centralWidget层的,那么,难道要想使用鼠标事件就不能使用布局管理器了么?
解决办法:
1.重写控件的鼠标事件!这个方法的话,如果窗体上很多控件,那得写死去,所以我放弃了这种方法。
2.使用事件过滤器EventFilter,该方法简单可行。我们可以改用这种方法,不但可以监视鼠标移动,也可以监测鼠标的其他时间。
步骤:1>给要监视的窗体、控件安装事件过滤器;
2>为了监视鼠标移动事件,开启鼠标追踪,即setMouseTracking(1);
3>给窗体添加eventFilter成员函数
4>重写eventFilter
程序举例:
project.cpp
构造函数中:
//安装事件过滤器
imgLab1->installEventFilter(this);
imgLab2->installEventFilter(this);
btn1->installEventFilter(this);
btn2->installEventFilter(this);
//开启鼠标移动跟踪
imgLab1->setMouseTracking(true);
imgLab2->setMouseTracking(true);
btn1->setMouseTracking(true);
btn1->setMouseTracking(true);
centralWidget()->setMouseTracking(true);
this->setMouseTracking(true);
project.h
类定义中:
protected:
bool eventFilter(QObject *,QEvent *);//事件过滤器
project.cpp
成员函数定义:
bool SimilarProject::eventFilter(QObject* o, QEvent* e)
{
if((o == btn1) && (e->type() == QEvent::MouseButtonPress))
{
}
else if((o == btn2) && (e->type() == QEvent::MouseButtonPress))
{
}
else if((o == imgLab1) && (e->type() == QEvent::MouseButtonPress))
{
}
else if((o == imgLab1) && (e->type() == QEvent::MouseMove))
{
}
else if ((o == imgLab1) && (e->type() == QEvent::MouseButtonRelease))
{
}
return false;
}
注:如果返回true则表示不过滤该事件,返回false则可持续过滤事件