1、事件过滤器是 Qt 提供的一种机制,允许一个对象拦截并处理发送给另一个对象的事件。可以实现以下功能:
拦截事件:在事件到达目标对象前截获
修改事件: 改变事件的属性或行为
阻止事件:不让事件继续传递到目标对象
添加额外处理:在不修改原类的情况下增加功能
2、使用事件过滤器分三步:
步骤1:在监听类中重写 eventFilter()函数
// 在头文件中声明
protected:
bool eventFilter(QObject *obj, QEvent *event) override;
// 在源文件中实现
bool MyClass::eventFilter(QObject *obj, QEvent *event)
{
// 判断是哪个对象的事件
if (obj == m_targetWidget)
{
// 判断是什么类型的事件
if (event->type() == QEvent::MouseButtonDblClick)
{
// 处理双击事件
qDebug() << "双击了目标控件";
return true; // 返回true表示事件已被处理,不再向下传递
}
}
// 对于其他事件,交给默认处理
return QMainWindow::eventFilter(obj, event);
}
步骤2:为目标对象安装事件过滤器
// 在构造函数或初始化函数中
m_targetWidget->installEventFilter(this);
步骤3:在析构函数中移除事件过滤器(可选)
// 析构时移除
m_targetWidget->removeEventFilter(this);
3、 完整示例
// mainwindow.h
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
protected:
bool eventFilter(QObject *obj, QEvent *event) override;
private:
QPushButton *m_btn;
QLabel *m_label;
};
// mainwindow.cpp
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
{
// 创建控件
m_btn = new QPushButton("按钮", this);
m_label = new QLabel("标签", this);
// 安装事件过滤器
m_btn->installEventFilter(this);
m_label->installEventFilter(this);
}
bool MainWindow::eventFilter(QObject *obj, QEvent *event)
{
// 监控按钮的鼠标悬停
if (obj == m_btn) {
if (event->type() == QEvent::Enter) {
m_btn->setText("鼠标进来了");
return true;
}
if (event->type() == QEvent::Leave) {
m_btn->setText("鼠标离开了");
return true;
}
}
// 监控标签的双击
if (obj == m_label) {
if (event->type() == QEvent::MouseButtonDblClick) {
m_label->setText("被双击了!");
return true;
}
}
// 其他事件交给基类处理
return QMainWindow::eventFilter(obj, event);
}