QT从入门到实战x篇_26_事件过滤器eventfilter(在程序将事件分发到事件分发器前,可以利用过滤器拦截;步骤2步:给控件安装事件过滤器、重写eventfilter事件)

上篇QT从入门到实战x篇_25_event事件分发器(用于事件的分发;也可以做拦截操作,不建议;bool event(QEvent* e);返回值如果是true代表用户处理这个事件,不向下分发了)了解了QT中事件的机制,本篇将会介绍QT中的事件过滤器。

总结:

  1. 在程序将事件分发到事件分发器前,可以利用过滤器拦截
  2. 步骤:
    (1)给控件安装事件过滤器
    (2)重写eventfilter事件

1. 事件过滤器eventfilter


上篇中介绍到如果想要拦截事件,是在 bool event(QEvent* e)的事件分发器中进行的,也可以通过事件过滤器在程序分发到事件分发器之前再做一次高级拦截。
分为两个步骤: (1)给控件安装事件过滤器;(2)重写eventfilter事件。

在这里插入图片描述
具体实现代码如下:

  • widget.h
    //重写事件过滤器事件
    bool eventFilter(QObject *watched, QEvent *e);
  • widget.cpp
//给label安装事件过滤器
//步骤1:安装事件过滤器
 ui->label->installEventFilter(this);

//步骤2:重写eventfilter事件
bool Widget::eventFilter(QObject *watched, QEvent *e)
{
  if(watched==ui->label)
  {
      if(e->type()==QEvent::MouseButtonPress)
      {
          //将子类强转为父类
          QMouseEvent* ev=static_cast<QMouseEvent *>(e);
          QString str=QString::fromLocal8Bit("事件过滤器中::鼠标按下了 x= %1 y=%2 globalx=%3 globaly=%4").arg(ev->x()).arg(ev->y()).arg(ev->globalX()).arg(ev->globalY());
          qDebug()<<str;

          //true代表用户自己处理这个事件,不向下分发
          return true;
      }
  }

  //其他默认处理
  return QWidget::eventFilter(watched,e);
}

运行结果:在控件的事件过滤器中进行了拦截
在这里插入图片描述

2. 学习视频地址:QT从入门到实战x篇_26_事件过滤器

整体代码:

  • widget.h
#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

    //重写定时器事件
    void timerEvent(QTimerEvent* ev);
    int id1;
    int id2;

    //重写事件过滤器事件
    bool eventFilter(QObject *watched, QEvent *e);

private:
    Ui::Widget *ui;
};
#endif // WIDGET_H
  • widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include <QTimer> //定时器的类
#include<QMouseEvent>
#include<QDebug>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    //启动计时器
    id1=startTimer(1000);//参数1 间隔 单位 毫秒

    id2=startTimer(2000);

    //定时器的第二种方式
    QTimer* timer=new QTimer(this); //使用this将其加在对象树上

    //启动定时器 定时器每隔0.5秒就发出一个信号
    timer->start(500);

    //将timeout的信号与this的lambda表达式绑定,每超过0.5秒就执行一次
    connect(timer,&QTimer::timeout,[=](){

        static int num3=1;
        //label4 每0.5秒加1
        ui->label_4->setText(QString::number(num3++));

    });

    //点击一下暂停按钮,就停止计时器
   connect (ui->pushButton,&QPushButton::clicked,[=]()
   {
       timer->stop();
   });

   //给label安装事件过滤器
   //步骤1:安装事件过滤器
   ui->label->installEventFilter(this);
}


//timerEvent的重写,需要设置启动时机
void Widget::timerEvent(QTimerEvent* ev)
{
    if(ev->timerId()==id1){
        static int num=1;
        ui->label_2->setText(QString::number(num++));
    }

if(ev->timerId()==id2){
    static int num2=1;
    ui->label_3->setText(QString::number(num2++));
}

}
//步骤2:重写eventfilter事件
bool Widget::eventFilter(QObject *watched, QEvent *e)
{
  if(watched==ui->label)
  {
      if(e->type()==QEvent::MouseButtonPress)
      {
          //将子类强转为父类
          QMouseEvent* ev=static_cast<QMouseEvent *>(e);
          QString str=QString::fromLocal8Bit("事件过滤器中::鼠标按下了 x= %1 y=%2 globalx=%3 globaly=%4").arg(ev->x()).arg(ev->y()).arg(ev->globalX()).arg(ev->globalY());
          qDebug()<<str;

          //true代表用户自己处理这个事件,不向下分发
          return true;
      }
  }

  //其他默认处理
  return QWidget::eventFilter(watched,e);
}

Widget::~Widget()
{
    delete ui;
}
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

十月旧城

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值