event->pos()返回一个位置,在窗口中重写鼠标点击事件,qDebug() << event->pos();
若是在设计者模式下在窗口中增加加控件(frame widget label), 以鼠标点击事件为例:默认情况下,这个位置是相对于整个窗口来说的(也就是说这个事件最终是由窗体的鼠标点击事件函数进行处理的),尽管我们点击在子控件上。当然了,若是点击在按钮类上,则这个事件传递不到窗口。
若是自定义控件增加到窗口中,同样以鼠标点击为例:默认情况下(自定义的部件中的鼠标点击事件不写(声明也不写)),这个位置输出后还是相对于整个窗口的,还是由窗体的鼠标点击事件进行处理。若是子控件写了鼠标点击事件函数(即使只写一个声明,与函数体,但函数体中并没有实现内容),这个位置是针对于这个部件的(可以在子部件中的鼠标点击事件中加上一个qDebug() << event->pos()方便观察),由部件进行处理此事件。这个事件传递不到窗口。
(以上两条,都是由于,事件处理函数在默认状态下(或者说最起码鼠标点击事件如此,这里与最下面的连接的内容有点差别,又或许我们想表达的默认状态有所不同:我这里是指,不要重写虚函数,声明什么的也不写,而他的意思是,重写虚函数,但是虚函数中什么也不写。笔者这里重找了一个博客,供参考:Qt事件的接受和忽略_qt事件忽略_十年编程老舅的博客-CSDN博客,这么一对比应该是我的理解正确。),是会继续向父部件传递的。
下面就是自定义的子部件中虚函数的重写: 下面两幅图片中的QWidget::mouseMoveEvent(event);改为QWidget::mousePressEvent(event);
上面若是放开注释,之后再追加一些代码,那些代码依旧执行完毕。
接下来我们在子部件中重写event函数,事件是由event函数进行分发的,我们在到发给mousePressEvent之前是可以对这个事件进行处理的,现在我们在event中忽视此事件(return false或ev->ignore()),其结果应该是,直接进入父部件的鼠标点击事件虚函数中。不走自己(子部件)的重写的mousePressEvent虚函数中了。 已经验证,结果正确。
验证时发现一个东西(当然了是错误的写法):
这里怎么又走了子部件的虚函数和父部件的虚函数呢,原因在于:
if(ev->type() == QEvent::MouseButtonPress){ ev->ignore(); //return false;也是一样的,这时,已经说明,我们不处理它,并且它也去找寻其他的部件进行处理它了。 QWidget::event(ev); //调用子部件的父类(注意是继承关系的父类)的event函数,它是默认的,是会让子部件处理的。故此这里即走父部件的虚函数(鼠标点击事件处理函数),也走子部件的虚函数。 }
应当改为
if(ev->type() == QEvent::MouseButtonPress){ ev->ignore(); //return false; else QWidget::event(ev); }
补充:
if(ev->type()==QEvent::MouseButtonPress){ return false//return true; //或者不写 }else{ QWidget::event(ev); } //上述三种情况下,都不会进入子部件的重写的鼠标按下事件处理函数。
若是将同一次鼠标按下事件多次传递给父部件的话,父部件只响应一次(优化了)。
若是自定义控件“放到”(不指定父部件)窗口中,以鼠标点击事件来说,无论鼠标事件存在与否,即使点击到自定义部件位置,event->pos还是有输出,输出的还是相对于窗口的位置,即是窗口的鼠标点击函数进行处理的。
(这不是废话吗!你都没指定父类,这个部件都不在窗口中欸!!!)
事件接收与处理:https://blog.csdn.net/kangkanglhb88008/article/details/122143306