【QT】事件分发器/事件过滤器/事件处理的介绍和使用

news2025/1/16 8:20:42

事件分发函数 event()

在这里插入图片描述

事件分发器:返回值 bool

如果返回时true,代表用户要处理事件,不再分发事件了。

  • 事件对象创建完毕后,Qt 将这个事件对象传递给QObject的event()函数。
  • event()函数并不直接处理事件,而是将这些事件对象按照它们不同的类型,分发给不同的事件处理(eventhandler)。

因此如上所述,event()函数主要用于事件的分发。所以,如果你希望在事件分发之前做一些操作,就可以重写这个event()函数了。

event事件

#include <QEvent>
  • 用途:用于事件的分发
  • 也可以用作拦截事件(不建议)

例如,我们希望在一个QWidget组件中监听 tab 键的按下,那么就可以继承QWidget,并重写它的event()函数,来达到这个目的

在这里插入图片描述

//事件分发器
bool mylabel::event(QEvent *e)
{    
if(e->type() == QEvent::KeyPress)
    {
       静态类型转换
        QKeyEvent *keyEvent = static_cast<QKeyEvent*>(e);
        if(keyEvent->key()==Qt::Key_Tab)
        {
            qDebug()<<"tab had pressed";
            return true;
        }
    }
    return QWidget::event(e);
}

做一个拦截的目的时,说明它可以做拦截。

实际应用就是鼠标事件就用鼠标相应的函数操作,定时器就用定时器。


//事件分发器
bool mylabel::event(QEvent *e)
{
 //如果键盘按下,在event事件分发中做拦截操作
    if(e->type() == QEvent::MouseButtonPress)
    {
        //静态类型转换
         QMouseEvent *ev = static_cast<QMouseEvent*>(e);
         QString str = QString("Event函数中,鼠标按下了 x = %1,y=%2 globalX =%3 globalY = %4").arg(ev->x()).arg(ev->y()).arg(ev->globalX()).arg(ev->globalY());
         qDebug()<<str;
    }

}

//会做类型检查,相对安全,但是带来的成本高于static_cast

 QMouseEvent *ev  = dynamic_cast<QMouseEvent*>(e);//会做类型检查,相对安全,但是带来的成本高于static_cast

事件过滤器(了解即可)

  1. 事件过滤器可以对需要的组件接收到的事件进行过滤,以及监控
  2. 任意的QObject对象都可以作为事件过滤器使用
  3. 事件过滤器的实现,需要重写eventFilter()函数
  4. 组件要想被监控,则需要通过installEventFilter()安装事件过滤器
  5. 事件过滤器能够决定是否将事件转发给组件对象,如下图所示:

在这里插入图片描述

obj->installEventFilter(filterObject);常常是obj->installEventFilter(this).

  • 发送到obj的所有事件, 都会先发送到filterObject的eventFilter()方法,
  • 即filterObject会过滤obj的事件, 这样就不用为了实现一个事件而要去继承, 再实现一个类, 完成如mouse event, key event等了, 只用在当前类中就可以通过事件过滤来完成.

在这里插入图片描述

在程序将事件分发到事件分发器前,可以利用过滤器拦截

1.给控件安装事件过滤器

2.重写eventFilter函数(obj,sv)

public:
    explicit Event(QWidget *parent = nullptr);
    ~Event();
    //重写事件过滤器事件
    bool eventFilter(QObject*obj,QEvent*e);
#include "event.h"
#include "ui_event.h"
#include <QDebug>
#include <QMouseEvent>
#include <QEvent>
Event::Event(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Event)
{
    ui->setupUi(this);
    //步骤一安装事件过滤器
    ui->label->installEventFilter(this);
    //步骤2L重写eventfilter事件
}

 bool Event::eventFilter(QObject*obj,QEvent*e)
 {
     if(obj == ui->label)
     {
     if(e->type() == QEvent::MouseButtonPress)
     {
         //静态类型转换
          QMouseEvent *ev  = dynamic_cast<QMouseEvent*>(e);//会做类型检查,相对安全,但是带来的成本高于static_cast
         //QMouseEvent *ev = static_cast<QMouseEvent*>(e);
          QString str = QString("EventFilter函数中,鼠标按下了 x = %1,y=%2 globalX =%3 globalY = %4").arg(ev->x()).arg(ev->y()).arg(ev->globalX()).arg(ev->globalY());
          qDebug()<<str;
      }
     }
     //其他默认处理
     return QWidget::eventFilter(obj,e);
 }
Event::~Event()
{
    delete ui;
}

在这里插入图片描述

Qt事件处理介绍

  • Qt平台会将系统产生的消息转换为Qt事件
  • Qt事件是一个QEvent的对象
  • Qt事件用来描述程序内部或外部发生的动作
  • 任意的QObject对象都具备事件处理的能力

如下图所示,可以看到QEvent的子类非常之多:

在这里插入图片描述

  • **QInputEvent:**用户输入事件
  • **QDropEvent:**用户拖放事件
  • **QPaintEvent:**描述操作系统绘制GUI动作的事件
  • **QCloseEvent:**用户关闭窗口事件
  • **QTimerEvent:**计时器事件

事件处理方式顺序

1.Qt事件产生后立即被分发到QWidget对象

2.QWidget中的**event(QEvent*)**进行事件处理

3.event()根据事件类型调用不同的事件处理函数

4.在事件处理函数中发送Qt中预定义的信号

5.调用信号关联的槽函数

举个例子:

1.当点击按钮后,将会触发**鼠标事件,调用event(QEvent*)**成员函数

3.调用**mouseReleaseEvent(QMouseEvent*)**成员函数

4.调用**click()**成员函数

5.触发信号SIGNAL(clicked());

同样,当用户点击窗口的关闭按钮时,也会触发closeEvent()事件函数,该函数需要重写,才能实现

 void MainWindow::closeEvent(QCloseEvent *event)
{
     if (maybeSave())                        //如果还有需要保存的数据
    {
         writeSettings();
         event->accept();
    } 
     else                                    //取消关闭窗口
    {
         event->ignore();
    }
 }

类似的还有**keyEvent()**获取键盘事件函数, **keyReleaseEvent()**键盘按下事件函数,enterEvent光标进入组件事件函数, leaveEvent光标离开组件事件函数等等。

其中QCloseEvent继承与QEvent,在QEvent中常用成员函数有

void  accept ();    //接收者处理当前事件

void  ignore ();    //接收者忽略当前事件,忽略后,事件可能传递给父组件

bool isAccepted();  //判断当前事件是否被

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1496876.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

PS在图片上直线、虚线、曲线

使用钢笔工具和直线工具都可以画直线&#xff0c;

script的defer和async的理解

场景一 js阻碍了dom元素的渲染 场景二 加了defer&#xff0c;结果跟场景一一样&#xff0c;所以defer对script标签内的代码不期待延迟执行的作用 场景三 script标签没有defer属性&#xff0c;不敢是不是通过src引入代码&#xff0c;结果一样 场景四 加了defer&#xff0c;获…

搭建的svn 1.14.1,拉取代码时候没输入账户密码就报错 auth failed

这边在ubuntu里面搭的svn server&#xff0c;但是拉代码的是否一直报错 auth faield&#xff0c;一开始以为是有auth cache&#xff0c;去设置里面清楚了&#xff0c;windows 里面也清楚了&#xff0c;但是还是报错 问题原因 一直排查才发现&#xff0c;我新增用户的时候&…

SpringBoot中的异常处理器

我们在以上的开发中,统一使用Result返回固定的数据格式给到前端,但是由于程序可能会出现BUG等问题,会导致最终返回给前端的数据,在异常情况下就又不统一了 为了实现在异常情况出现时,也能正常给前端返回统一的数据格式,我们需要使用 异常处理器 定义异常处理器需要使用RestCo…

Mac系统:mysql+jdk+neo4j

mysql 指令 //启动MySQL服务 sudo /usr/local/mysql/support-files/mysql.server start//停止MySQL服务 sudo /usr/local/mysql/support-files/mysql.server stop //连接MySQL数据库&#xff0c;在进行这一步前要先关掉服务 mysql -u root -p //检查MySQL服务状态 sudo /us…

【Unity】ABB CRB 15000 外部引导运动

一、RobotStudio控制器的文件系统和配置参数 HOME&#xff1a;控制器文件系统的根目录或起始点。配置&#xff1a;机器人控制器的配置设置和参数。外件信息&#xff1a;连接到机器人的外部组件的信息。I/O 系统&#xff1a;输入/输出系统&#xff0c;管理机器人和外部设备之间的…

基于dashscope在线调用千问大模型

前言 dashscope是阿里云大模型服务平台——灵积提供的在线API组件。基于它&#xff0c;无需本地加载大模型&#xff0c;通过在线方式访问云端大模型来完成对话。 申请API key 老规矩&#xff1a;要想访问各家云端大模型&#xff0c;需要先申请API key。 对于阿里云&#x…

uniapp图片涂鸦插件(支持多种涂鸦方式,图片放大缩小)

工程地址https://gitee.com/geshijia/ct-graffiti ct-graffiti涂鸦组件使用说明 参考说明 参考链接&#xff1a;https://github.com/ylyuanlu/yl-graffiti 感谢作者的付出&#xff0c;给我提供了一些思路&#xff0c;并做了如下优化&#xff1a; 增加图片放大缩小移动功能添…

UML简述(项目立项、设计、需求整理必备)

UML目录 前言1、UML概述1.1、基本概念1.2、UML图类型说明1.3、UML的41视图 2、UML图详细图示2.1、类图2.2、对象图2.3、组件图2.4、部署图2.5、包图2.6、用例图2.7、状态图2.8、活动图2.9、时序图2.10、通信图&#xff08;协作图&#xff09;2.11、定时图&#xff08;计时图&am…

08 |「Fragment 」

前言 实践是最好的学习方式&#xff0c;技术也如此。 文章目录 前言一、简介1、是什么2、为什么要有 Fragment3. Fragment 详细解释 二、Fragment 与 Activity 的直观理解三、Fragment 的创建1、Fragment 的创建方式2、Fragment 的增删替查1&#xff09; 替换&#xff08;常见&…

哪个牌子宠物空气净化器好?质量好的宠物空气净化器推荐

即使我们很爱自家的宠物&#xff0c;但我们也无法否认处理房间里飘荡的宠物毛发和皮屑&#xff0c;以及那些令人不快的气味&#xff08;比如地毯上的意外和垃圾桶里的气味&#xff09;的挑战。对于过敏患者来说&#xff0c;这几乎是无法忍受的。寻找有效的方法来减少这些问题对…

电子邮件怎么发送?如何发送匿名电子邮件?

电子邮件发送的详细步骤&#xff1f;电子邮件的发送方式有哪些&#xff1f; 掌握如何发送电子邮件&#xff0c;尤其是如何发送匿名电子邮件&#xff0c;对于保护个人隐私、进行安全交流具有重要意义。下面&#xff0c;AokSend就来详细探讨一下电子邮件的发送方法以及如何发送匿…

转录组总结

1. 软件安装 2.转录组分析步骤&#xff1a; ① 建立环境 #建立python2.7的环境&#xff0c;大部分的转录组信息都需要在Python2的环境下进行 conda create -n py2env python2.7 source activate py2env ② 获取fastqc报告 #单个报告 fastqc -t 15 /home/yinwen/biosoft/DN…

17-Java解释器模式 ( Interpreter Pattern )

Java解释器模式 摘要实现范例 解释器模式&#xff08;Interpreter Pattern&#xff09;实现了一个表达式接口&#xff0c;该接口解释一个特定的上下文 这种模式被用在 SQL 解析、符号处理引擎等 解释器模式提供了评估语言的语法或表达式的方式&#xff0c;它属于行为型模式 …

数据库(mysql)-新手笔记-基本知识点(1)

基本概念 数据库 Database :存储数据的容器 表 Table : 在数据库中存储的基本结构,它由行和列组成 行 Row : 表中的一条记录 列 Column : 表中的字段,定义了数据的类型和约束 数据类型 数据值 如 INT(整型),FLAOT(浮点型) ,DECIMAL (精确小数点) 字符串 如 VARCHAR(可变长度字…

Linux第68步_旧字符设备驱动的一般模板

file_operations结构体中的函数就是我们要实现的具体操作函数。 注意&#xff1a; register_chrdev()和 unregister_chrdev()这两个函数是老版本驱动使用的。现在新字符设备驱动已经不再使用这两个函数&#xff0c;而是使用Linux内核推荐的新字符设备驱动API函数。 1、创建C…

更快更强,Claude 3全面超越GPT4,能归纳15万单词

ChatGPT4和Gemini Ultra被Claude 3 AI模型超越了&#xff1f; 3月4日周一&#xff0c;人工智能公司Anthropic推出了Claude 3系列AI模型和新型聊天机器人&#xff0c;其中包括Opus、Sonnet和Haiku三种模型&#xff0c;该公司声称&#xff0c;这是迄今为止它们开发的最快速、最强…

NLP:自定义模型训练

书接上文&#xff0c;为了完成指定的任务&#xff0c;我们需要额外训练一个特定场景的模型 这里主要参考了这篇博客&#xff1a;大佬的博客 我这里就主要讲一下我根据这位大佬的博客一步一步写下时&#xff0c;遇到的问题&#xff1a; 文中的cfg在哪里下载&#xff1f; 要不…

Jellyfin影音站点搭建并结合内网穿透实现远程观看本地影视资源

文章目录 1. 前言2. Jellyfin服务网站搭建2.1. Jellyfin下载和安装2.2. Jellyfin网页测试 3.本地网页发布3.1 cpolar的安装和注册3.2 Cpolar云端设置3.3 Cpolar本地设置 4.公网访问测试5. 结语 1. 前言 随着移动智能设备的普及&#xff0c;各种各样的使用需求也被开发出来&…

国创证券|沪指震荡微跌,资源股集体拉升,黄金概念持续活跃

7日早盘&#xff0c;两市股指盘中震动下探&#xff0c;创业板指、科创50指数跌超1%&#xff0c;北证50指数跌逾2%&#xff1b;北向资金小幅流出。 截至午间收盘&#xff0c;沪指跌0.16%报3035.04点&#xff0c;深证成指跌0.68%&#xff0c;创业板指跌1.48%&#xff0c;科创50指…