【引自博主-unclerunning】https://blog.csdn.net/unclerunning/article/details/70226794#qt
Qt事件过滤器详解
eventFilter是虚函数,因此在#派生类木有过滤器函数(超类有)的情况下,可直接安装派生类中UI之具体控件到超类的过滤器。即(举例):
//超类 bool WidgetSuper::eventFilter(QObject *pObject, QEvent *pEvent) { //..Special Deal Event Code //comm return QWidget::eventFilter(pObject, pEvent); } //派生类 Form_1::Form_1(QWidget *parent) : WidgetSuper(parent), ui(new Ui::Form_1) { ui->setupUi(this); ui->pushButton->installEventFilter(this); } //bool Form_1::eventFilter(QObject *pObject, QEvent *pEvent) //{ //..Special Deal Event Code //personal //return WidgetSuper::eventFilter(pObject, pEvent); //}一旦派生类自身也重写eventFilter函数,若此时还想使用超类过滤器中的事件处理,则必须在派生类的eventFilter函数最后,调用其父类同名函数。事件会向父窗口传递,但是不会自动向父类传递。
//代码注释 场景: PushButton-1是ui->stackedWidget#Widget_Page1的一个StrongFocus的控件,click或Tab或setFocus将窗口焦点设置在PushButton-1上,然后按下Key_A键盘,希望在ui对应类的过滤器函数中能捕获到这一事件! //方案1 //ui->stackedWidget->installEventFilter(this);
//方案2 this->installEventFilter(this); 因为QPushButton本身不会对Key_A有任何的处理,故此事件会向其父窗口传递,若还不处理,继而向祖父窗口传递。在各级父对象中,若有安装过滤器的,则执行他们的过滤器函数,若都没有则该事件将被系统做默认处理。
控件的焦点属性,对键盘事件的捕获起作用(键盘事件首先有系统分配到焦点控件)。
给QObject对象安装事件过滤器:对象用installEventFilter()后,所有达到目标控件的事件都首先到达监视对象的eventFilter()函数。如果一个对象有多个事件过滤器,过滤器按顺序激活,先到达最近安装的监视对象,最后到达最先安装的监视对象。
写过滤器时,可以插一嘴,QWidget::grabMouse 试试父窗口强占的鼠标事件在其EventFilter中分发给其子控件后,会不会再次被他抢来,从而进入无限循环。 测试结果,到是没有无限循环,但是确实又被捕获了。对于那些可以直接调用执行(不必事件转发)的情况,这种方案勉强可以使用。
使用过滤器改变窗口或控件的原始响应,如,按键响应、鼠标响应等–可以展开
//核心:转换rect为全局区域 //translated
QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(pEvent); //目标区域左上角->转全局坐标 QPoint posOffset = m_pRecvWdt->mapToGlobal(QPoint(0, 0)); //目标矩形(TP:0-0)->全局区域 QRect rectGlobal = m_pRecvWdt->rect()->translated(posOffset); //判断鼠标位置在关注范围内 return rectGlobal.contains(mouseEvent->globalPos()) ? true, false;【引自博主-lfsblackoverflow】 https://www.cnblogs.com/lfsblack/p/5279143.html
模态与非模态情况下的事件循环-
有个问题,对于new的自定义事件,postEvent后,要不要我们自己去delete呢?[答案只能去源码中寻找la]
先来看一篇:Qt中postEvent和sendEvent函数 https://blog.csdn.net/xiaoyink/article/details/79404377
走,去看源码喽,直接顺着postEvent的源码一路F2向下查,不难发现,步步return前都会存在delete过程。再看这个函数的注释:The event must be allocated on the heap since the post event queue will take ownership of the event and delete it once it has been posted. It is {not safe} to access the event after it has been posted. When control returns to main event loop, all events that are stored in the queue will be sent using the notify() function.