前言
使用事件过滤器之前需要了解qt事件的运行机制。
这里举一个应用场景来记录事件过滤器的整个使用过程。
实现这样一个功能,在一个窗口上追踪鼠标的的移动位置,如果这个窗口是一个单一的窗口,没有任何子控件,那么只需要开启鼠标追踪,然后重写mouseMoveEvent(),就可以实现功能了。
但是如果有子控件的情况下,鼠标移动到子控件上时,移动事件会优先被子控件处理,那如果要在一个复杂的页面上完成这样的功能,岂不是需要重写所有子控件的鼠标事件?
事件过滤机制
Qt 在提供事件循环服务时,为了QObject提供了
bool eventFilter(QObject* watched, QEvent* event) override;
这个函数会在event()函数被调用之前调用,如果返回值为true,那么表面这个事件被处理了,这个事件将跳过event()函数的处理。
并且QObject还提供了
void QObject::installEventFilter(QObject *filterObj)
这个函数可以将一个QObject作为一个过滤器,安装到另一个QObject对象,那么安装之后,在调用自己本身的eventFilter()之前会先调用过滤器的这个函数。
事件过滤器可以设置多个,在调用时会根据安装的先后顺序调用。
示例
#pragma once
#include <QWidget>
#include <QVBoxLayout>
#include <QLabel>
#include <QTextEdit>
namespace EFT {
class widget :public QWidget {
public:
widget(QWidget* parent = 0);
~widget();
protected:
bool eventFilter(QObject* watched, QEvent* event) override;
private:
QVBoxLayout* vLaout;
QLabel* label;
QTextEdit* textEdit;
};
}
#include "EventFilterTest.h"
#include <QEvent>
#include <QMouseEvent>
#include <QDebug>
EFT::widget::widget(QWidget* parent /*= 0*/)
:QWidget(parent)
{
//初始化窗口布局
vLaout = new QVBoxLayout();
label = new QLabel();
label->setText("This is a label");
textEdit = new QTextEdit();
vLaout->addWidget(label);
vLaout->addWidget(textEdit);
this->setLayout(vLaout);
//开启鼠标追踪
this->setMouseTracking(true);
label->setMouseTracking(true);
textEdit->viewport()->setMouseTracking(true);
//安装过滤器
label->installEventFilter(this);
textEdit->viewport()->installEventFilter(this);
this->installEventFilter(this);
}
EFT::widget::~widget()
{
textEdit->deleteLater();
label->deleteLater();
vLaout->deleteLater();
}
bool EFT::widget::eventFilter(QObject* watched, QEvent* event)
{
if (event->type() == QEvent::MouseMove)
{
auto e = dynamic_cast<QMouseEvent*>(event);
label->setText(QString("pos x: %1 y: %2").arg(e->globalX()).arg(e->globalY()));
return true;
}
return QWidget::eventFilter(watched, event);
}
运行结果:
-
就是直接给QTextEdit设置过滤器,无法捕捉到事件,猜测时因为这个控件内部被小部件铺满,所以事件被小部件给处理了,所以需要调用viewport()函数获取小部件对象,将过滤器安装到小部件中。
-
如果不给自己安装过滤器,似乎也不会主动的调用eventFilter()函数,这和我之前设想的不太一样。

文章评论