lps_683 阅读(105) 评论(0)

     今天要探讨一个非常非常蛋疼的问题,就是关于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则可持续过滤事件