首页 > 其他分享 >【QT】事件分发器 & 事件过滤器

【QT】事件分发器 & 事件过滤器

时间:2024-07-28 20:25:46浏览次数:16  
标签:分发 Widget QT QEvent 事件 过滤器 event

qt 系统 - 事件分发器 and 事件过滤器

一、事件分发器

1. 事件分发器概念

在 Qt 中,事件分发器(Event Dispatcher) 是一个核心概念,用于处理 GUI 应用程序中的事件。事件分发器负责将事件从⼀个对象传递到另⼀个对象,直到事件被处理或被取消。每个继承自 QObject 类或 QObject 类本身都可以在本类中重写 bool event(QEvent *e) 函数,来实现相关事件的捕获和拦截。

2. 事件分发器工作原理

在 Qt 中,我们发送的事件都是传给了 QObject 对象,更具体点是传给了 QObject 对象的 event() 函数。所有的事件都会进入到这个函数里面,那么我们处理事件就要重写这个 event() 函数。event() 函数本⾝不会去处理事件,而是根据 事件类型(type值)调用不同的事件处理函数。事件分发器就是工
作在应用程序向下分发事件的过程中,如下图:

在这里插入图片描述

如上图,事件分发器⽤于分发事件。在此过程中,事件分发器也可以做拦截操作。事件分发器主要是通过 bool event(QEvent *e) 函数来实现。其返回值为布尔类型,若为 ture,代表拦截,不向下分发。

Qt 中的事件是封装在 QEvent 类中,在 Qt 助手中输入 QEvent 可以查看其所包括的事件类型,如下图示:

在这里插入图片描述

在这里插入图片描述

示例代码:

1、在 “widget.h” 头⽂件中声明 ⿏标点击事件 和 事件分发器;如下图⽰:

			class Widget : public QWidget
			{
			    Q_OBJECT
			
			public:
			    Widget(QWidget *parent = nullptr);
			    ~Widget();
			
			    // 鼠标点击事件
			    void mousePressEvent(QMouseEvent* event);
			
			    // 通过事件分发器拦截鼠标按下事件
			    bool event(QEvent* event);
			
			private:
			    Ui::Widget *ui;
			};

2、在 “widget.cpp” ⽂件中实现 ⿏标点击事件 和 拦截事件;

			#include <QDebug>
			#include <QMouseEvent>
			void Widget::mousePressEvent(QMouseEvent *event)
			{
			    if(event->button() == Qt::LeftButton) {
			        qDebug() << "鼠标左键被按下!";
			    }
			}
			
			bool Widget::event(QEvent *event)
			{
			    if(event->type() == QEvent::MouseButtonPress) {
			        qDebug() << "Event 中鼠标被按下!";
			        return true; // return true 代表不向下分发
			    }
			    // 其它事件交给父类处理(默认处理)
			    return false;
			}

执行效果如下,当鼠标左键点击窗口时,就会执行 event 函数,而不会执行 mousePressEvent 函数:

在这里插入图片描述

二、事件过滤器

在 Qt 中,⼀个对象可能经常要查看或拦截另外⼀个对象的事件,如对话框想要拦截按键事件,不让别的组件接收到,或者修改按键的默认值等。通过上面的学习,我们已经知道,Qt 创建了 QEvent 事件对象之后,会调用 QObjectevent() 函数处理事件的分发。显然,我们可以在 event() 函数 中实现拦
截的操作。由于 event() 函数是 protected 的,因此,需要继承已有类。如果组件很多,就需要重写很多个 event() 函数。这当然相当麻烦,更不用说重写 event() 函数还得小心一堆问题。好在 Qt 提供了另外⼀种机制来达到这一目的:事件过滤器

事件过滤器是在应用程序分发到 event 事件分发器之前,再做⼀次更高级的拦截。如下图示:

在这里插入图片描述

事件过滤器的⼀般使用步骤:

  • 安装事件过滤器;
  • 重写事件过滤器函数:eventfilter()

代码示例:

1、设计 UI 文件,拖入一个 label,如下图示;

在这里插入图片描述

3、在项目新添加⼀个类:MyLabel

先选中项目名称 QEvent_2,点击⿏标右键,选择 add new … ,弹出如下对话框,选择 Choose 即可:

在这里插入图片描述

4、选择:Choose … 后,弹出如下界面,按照如下形式创建即可:

在这里插入图片描述

5、此时项目中会新添加我们刚新建的头文件和cpp文件;
6、在 UI 文件中选中 Label,右键 ------> 提升为…;当点击 "提升为… " 之后,弹出如下对话框:

在这里插入图片描述

接下来按照下图选择即可:

在这里插入图片描述

7、在 “mylabel.h” 中声明 ⿏标点击事件 和 事件分发器:

			#include <QWidget>
			#include <QLabel>
			
			class myLabel : public QLabel
			{
			    Q_OBJECT
			public:
			    explicit myLabel(QWidget *parent = nullptr);
			    
			    // 鼠标点击事件
			    void mousePressEvent(QMouseEvent* event);
			    
			    // 事件分发器
			    bool event(QEvent* e);
			};

8、在 “mylabel.cpp” ⽂件中实现⿏标点击事件和事件分发器;

			#include <QMouseEvent>
			#include <QDebug>
			
			myLabel::myLabel(QWidget *parent) : QLabel(parent)
			{}
			
			void myLabel::mousePressEvent(QMouseEvent *event)
			{
			    QString str = QString("鼠标按下: x = %1, y = %2").arg(event->x()).arg(event->y());
			    qDebug() << str.toUtf8().data();
			}
			
			bool myLabel::event(QEvent *e)
			{
			    // 如果是鼠标按下,在event事件分发时拦截操作
			    if(e->type() == QEvent::MouseButtonPress) {
			        QMouseEvent* event = static_cast<QMouseEvent*>(e);
			        QString str = QString("Event 函数中鼠标按下: x = %1, y = %2").arg(event->x()).arg(event->y());
			        qDebug() << str.toUtf8().data();
			
			        return true; // 返回true,代表用户自己处理,不向下分发
			    }
			
			    return QLabel::event(e); // 其他事件交给父类处理
			}

9、在 “widget.h” 头文件中声明事件过滤器函数;

			class Widget : public QWidget
			{
			    Q_OBJECT
			
			public:
			    Widget(QWidget *parent = nullptr);
			    ~Widget();
			    
			    // 声明 eventfilter 事件
			    bool eventFilter(QObject* obj, QEvent* e);
			
			private:
			    Ui::Widget *ui;
			};

10、在 “widget.cpp” ⽂件中实现事件过滤器的两个步骤;

			#include <QEvent>
			#include <QMouseEvent>
			#include <QDebug>
			
			Widget::Widget(QWidget *parent)
			    : QWidget(parent)
			    , ui(new Ui::Widget)
			{
			    ui->setupUi(this);
			    
			    // 1. 给label安装事件过滤器,this:当前窗口安装事件过滤器
			    ui->label->installEventFilter(this);
			}
			
			// 2. 重写eventfilter事件
			bool Widget::eventFilter(QObject *obj, QEvent *e)
			{
			    // 判断控件
			    if(obj == ui->label) {
			        if(e->type() == QEvent::MouseButtonPress) {
			            QMouseEvent* event = static_cast<QMouseEvent*>(e);
			            QString str = QString("事件过滤器中鼠标按下:x = %1, y = %2").arg(event->x()).arg(event->y());
			            qDebug() << str.toUtf8().data();
			            
			            return true;
			        }
			    }
			    // 其它交给父类处理
			    return QWidget::eventFilter(obj, e);
			}

执行效果如下,当在标签中点击鼠标时不会执行 event 函数,而会执行 eventfilter 函数:

在这里插入图片描述

标签:分发,Widget,QT,QEvent,事件,过滤器,event
From: https://blog.csdn.net/YoungMLet/article/details/140246870

相关文章

  • 详细了解Servlet中过滤器和监听器的使用
    目录一、过滤器1.1概念1.2过滤器的实现1.3过滤器中方法的介绍1.4过滤器的执行过程二、监听器2.1概念2.2 监听器的实现2.3不同监听器接口的介绍1. ServletContextListener接口2. HttpSessionListener接口3. HttpSessionAttributeListener接口一、过滤......
  • Qt Android 实现全屏
    本文内容参考自:https://blog.csdn.net/jun4331247/article/details/807396621.新建JFullScreen.java,添加以下代码,放置在QT安装目录\android_armv7\src\android\java\src\org\qtproject\qt5\android\bindingspackageorg.qtproject.junj;importandroid.app.Activity;import......
  • 实战|Qt开发WordBN笔记软件#10 添加Font Awesome字体图标
    01背景【WordBN字远笔记】是天恩软件工作室开发的一款免费笔记软件;WordBN基于VS2019、Qt6.5开发,使用QtQuick(QML)开发语言。本课程将以【WordBN字远笔记】的界面为实战基础,详细介绍如何基于Qt/QML开发语言,从零开始开发一套真正的程序,包括国际化、版本发布、安装包制作等项目......
  • 【QT】QT 系统相关(事件、文件、多线程、网络、音视频)
    一、Qt事件1、事件介绍事件是应用程序内部或者外部产生的事情或者动作的统称。在Qt中使用一个对象来表示一个事件。所有的Qt事件均继承于抽象类QEvent。事件是由系统或者Qt平台本身在不同的时刻发出的。当用户按下鼠标、敲下键盘,或者是窗口需要重新绘制的时候,都会发......
  • 如何从 python 脚本将事件和上下文传递到 AWS lambda?
    我正在创建一个cli应用程序,我想用它来调用我的AWSlambda函数:@click.group(context_settings={"help_option_names":["-h","--help"]},invoke_without_command=True)@click.version_option(version=__version__,prog_name="experiment")def......
  • 【HW系列】事中迎战(2):安全事件监控与处置
    本章为该系列的第12篇,也是事中迎战的第2篇,这一节让我们聊聊演练期间工作量最大的一项任务----安全事件监控与处置。一、角色分组还记得【红蓝/演练】-事前准备(1)之演练组织中介绍的组织架构吗,实战阶段的主力军就是以下三个组:监控组,负责对安全告警进行处置,及时闭环安全事件或......
  • 如何在 Python 中从 Milesight TrafficX 摄像头、Post(MQTT、TCP/IP、HTTP) 获取数据?
    你好,祝你度过愉快的一天或一夜,我有这个MilesightTrafficX摄像头已启动并正在运行,仪表板中有一个名为POST的设置,您可以在下图中看到:我想要的是知道如何设置这些设置(基于实际上我的意思是)能够在我的Python代码中接收数据。无论协议如何,数据都将如下所示:......
  • 如何利用PyQt实现列表添加删除排序功能?
    本文介绍如何实现列表增加删除和排序的功能,效果如下:1页面设计1.1列表#列表数据 self.list=['福宝','萌兰','金虎','蓝天']#创建四行一列标准数据模型self.mode=QStandardItemModel(4,1)#将数据中的列表项作为标准数据模型输出......
  • js的回车事件
    在JavaScript中,处理回车事件可以通过监听键盘事件来实现。通常情况下,回车键的键码为13。以下是一个简单的示例代码,演示如何检测用户按下回车键://监听键盘事件document.addEventListener('keydown',function(event){  if(event.key==='Enter'){    //......
  • Qt连接GPS模块实现调用高德地图交互显示经纬度信息的功能
    最近需要设计一个qt界面,在里面通过串口接收并解析出gps模块的经纬度信息,再通过调用高德地图的api进行地图的显示,作为入门qt的项目踩了不少坑,特将这个项目开源出来,供初学者参考学习。项目链接放下边啦,欢迎大家star~https://github.com/daviddou2023/qt_screen_gps一.项目简介......