QT之事件系统

news2025/3/14 23:59:18

QT之事件系统

  • 1. 概述
  • 2. 事件的传递
  • 3. 事件类型
  • 4. 事件处理与事件过滤
  • 5. 自定义事件
    • 5.1 Demo
  • 6. 发送事件
  • 7. 参考

1. 概述

在QT中,事件均派生自QEvent抽象类,事件可以由任何派生自QObject的子类实例接收和处理。它们与widget关联性极强。

2. 事件的传递

当事件发生时,QT 通过构造适当的 QEvent 子类实例来创建一个事件对象来表示它,并通过调用其 event() 函数将其传递给 QObject 的特定实例

event() 函数本身不处理事件;它根据传递的事件类型,它会调用该特定类型事件的事件处理程序,并根据事件是被接受还是被忽略来发送响应。

传递的顺序如下:
在这里插入图片描述

3. 事件类型

大多数事件类型都有特殊的类,特别是 QResizeEvent、QPaintEvent、QMouseEvent、QKeyEvent 和 QCloseEvent。 每个类都是 QEvent 的子类并添加特定于事件的函数。 例如,QResizeEvent 添加了 size() 和 oldSize() 以使小部件能够发现它们的尺寸是如何改变的。

每个事件都有一个关联的类型,在 QEvent::Type 中定义,这可以用作运行时类型信息的方便来源,以快速确定给定事件对象是从哪个子类构造的。

具体的事件类型可参考,官网介绍

4. 事件处理与事件过滤

常用的事件处理方式如下:

  • 重写各种事件的虚函数
    如paintEvent()、mousePressEvent()等。这是最常见的方式,同时也是最简单和功能最弱的方式
  • 重写event()函数
    event()函数是所有对象的事件入口,QObject和QWidget中的实现,默认是把事件传递给特定的事件处理函数
  • 在特定对象上面安装事件过滤器
    该过滤器仅过滤该对象接收到的事件。
  • 在QCoreApplication::instance()上面安装事件过滤器
    该过滤器将过滤所有对象的所有事件,因此和notify()函数一样强大,但是它更灵活,因为可以安装多个过滤器。全局的事件过滤器可以看到 disabled 组件上面发出的鼠标事件。全局过滤器有一个问题:只能用在主线程。
  • 重写QCoreApplication::notify()函数
    这是最强大的,和全局事件过滤器一样提供完全控制,并且不受线程的限制。但是全局范围内只能有一个被使用(因为QCoreApplication是单例的)
    Qt 调用 QApplication 来发送一个事件,重新实现 notify()函数是在事件过滤器得到所有事件之前获得它们的唯一方法。事件过滤器使用更为便利。因为可以同时有多个事件过滤器。而 notify()函数只有一个。

5. 自定义事件

QT自定义事件的创建步骤如下:

  1. 继承QEvent类
  2. 定义一个事件类型的两种方式
    • QT中有两个宏用来定义了用户事件的最大边界(QEvent::MaxUser)和最小边界(QEvent::User)
    • QT事件系统注册自定义事件类型
      在上述步骤中可以创建出一个与系统事件类型不冲突的自定义事件类型,但是无法保证自定义事件类型不冲突。因此需要将自定义事件类型注册到QT事件系统中,这样若有相同的类型再次被注册时QT事件系统就可以处理自定义事件类型冲突的问题。注册函数如下:
      // 线程安全
      // registerEventType 若传入参数可用则返回此参数,否则返回QEvent::MaxUser和QEvent::User之间的值,若参数不在QEvent::MaxUser和QEvent::User之间则忽略参数
      static int QEvent::registerEventType ( int hint = -1 );
      

5.1 Demo

  • myevent.h
    #ifndef MYEVENT_H
    #define MYEVENT_H
    
    #include <QEvent>
    
    class MyEvent : public QEvent
    {
    public:
        MyEvent();
        int getValue();
        static Type eventType;
    private:
        int m_value;
    };
    
    #endif // MYEVENT_H
    
    
  • myevent.cpp
    #include "myevent.h"
    
    QEvent::Type MyEvent::eventType = (QEvent::Type)QEvent::registerEventType();
    MyEvent::MyEvent(): QEvent(eventType),
        m_value(1)
    {
    }
    
    int MyEvent::getValue()
    {
        return m_value;
    }
    
    
  • mainwindow.h
    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H
    
    #include <QMainWindow>
    
    QT_BEGIN_NAMESPACE
    namespace Ui { class MainWindow; }
    QT_END_NAMESPACE
    
    class MainWindow : public QMainWindow
    {
        Q_OBJECT
    
    public:
        MainWindow(QWidget *parent = nullptr);
        ~MainWindow();
        virtual bool event(QEvent *event) override;
    protected:
        // 自定义事件的处理(专门处理自定义事件的),也可以用event()函数处理
        virtual void customEvent(QEvent *event) override;
    private:
        Ui::MainWindow *ui;
    };
    #endif // MAINWINDOW_H
    
    
  • mainwindow.cpp
    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    #include "myevent.h"
    #include <QDebug>
    
    MainWindow::MainWindow(QWidget *parent)
        : QMainWindow(parent)
        , ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
        MyEvent* myEvent = new MyEvent;
        // 事件只能定义在堆上,不用手动释放,系统会自动释放
        qApp->postEvent(this,myEvent);
    }
    
    MainWindow::~MainWindow()
    {
        delete ui;
    }
    
    bool MainWindow::event(QEvent *event)
    {
        QEvent::Type eventType = event->type();
        if(eventType == MyEvent::eventType)
        {
            MyEvent* myEvent = dynamic_cast<MyEvent*>(event);
            qDebug() << "event" << eventType ;
            qDebug() << "event" << myEvent->getValue() ;
            event->ignore();
        }
        // 处理完成后继续传播事件,这样customEvent就会收到自定义事件
        return QObject::event(event);
    }
    
    void MainWindow::customEvent(QEvent *event)
    {
        QEvent::Type eventType = event->type();
        if(eventType == MyEvent::eventType)
        {
            // 这里默认是true
            qDebug() << "customEvent" << event->isAccepted();
            MyEvent* myEvent = dynamic_cast<MyEvent*>(event);
            qDebug() << "customEvent" << eventType ;
            qDebug() << "customEvent" << myEvent->getValue() ;
            //event->accept();
        }
    }
    

event()处理事件的时机比customEvent()处理的早

6. 发送事件

  1. sendEvent()
    sendEvent() 立即处理事件。 当它返回时,事件过滤器和/或对象本身已经处理了该事件。
    对于许多事件类,有一个名为 isAccepted() 的函数可以告诉您事件是被调用的最后一个处理程序接受还是拒绝。
  2. postEvent()
    postEvent() 将事件发布到队列中以供稍后分派。 下次 Qt 的主事件循环运行时,它会调度所有已发布的事件,并进行一些优化。 例如,如果有多个调整大小事件,它们将被压缩为一个。
    这同样适用于绘制事件:QWidget::update() 调用 postEvent(),它通过避免多次重绘来消除闪烁并提高速度。

7. 参考

  1. QT事件处理–notify()
  2. https://blog.csdn.net/qq_40729688/article/details/89500394
  3. 官方事件系统介绍文档

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

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

相关文章

有了这 4 款工具,老大再也不怕我写烂SQL了

一、mysqltuner.pl 是 MySQL 一个常用的数据库性能诊断工具&#xff0c;主要检查参数设置的合理性包括日志文件、存储引擎、安全建议及性能分析。针对潜在的问题&#xff0c;给出改进的建议。是 MySQL 优化的好帮手。 在上一版本中&#xff0c;MySQLTuner支持 MySQL / MariaD…

LightningChart JS v4.0.0 and LightningChart NET

LightningChart JS v4.0.0 引入了新的 DataGrid 组件、全面的折线图类型和视觉主题。2023 年 2 月 9 日 - 16:05 新版本特征 下一代色彩主题&#xff1a; 暗金。网络空间。绿松石六角形。光。光自然。自定义 - 创建您自己的下一代颜色主题。新的 DataGrid 组件 DataGrid 组件是…

linux基本功系列之tar命令实战

文章目录前言一. tar命令介绍二. 语法格式及常用选项三. 参考案例3.1 仅打包不压缩3.2 打包后使用调用压缩命令进行压缩3.3 列出文件的内容3.4 追加文件到tar命令中3.5 释放文件到指定的目录四 . 各种压缩方式的比较总结前言 大家好&#xff0c;又见面了&#xff0c;我是沐风晓…

开学季该准备哪款电容笔?2023平替电容笔推荐

如今&#xff0c;电容笔越来越受欢迎&#xff0c;性能也越来越好。所以&#xff0c;如何选择一款具有高性价比的电容笔就成了人们的重点关注。现在&#xff0c;越来越多的人开始使用电容笔&#xff0c;所以&#xff0c;人们都在寻求更好、更经济的电容笔。所以&#xff0c;什么…

21省人均GDP超过1万美元,北京以19.01万元继续稳居榜首

在过去的2022年&#xff0c;各省都交了优秀的“成绩单”&#xff0c;各省的经济强弱即将揭晓。广东与江苏的GDP均超过12万亿元&#xff0c;是31省中超过12万亿元的两个城市&#xff0c;GDP分别为12.91万亿元与12&#xff0c;18万亿元。山东省、浙江省、河南省紧随其后&#xff…

linux yum安装卸载jdk8

1>安装1 yum -y list java* 列出jdk列表2 yum install -y java-1.8.0-openjdk-demo.x86_64&#xff08;安装这个java -version 正常显示&#xff0c;但是javac不能用&#xff0c;因为yum install java 只是安装了java的运行时环境&#xff0c;并不支持编译&#xff0c;安装成…

如何在线批量压缩PDF

PDF格式文档是我们日常比较常用的格式文档之一&#xff0c;那么有什么方法可以减小PDF大小呢&#xff1f;如果PDF比较多是否能批量处理呢&#xff1f; 首先打开浏览器搜索speedpdf就能找到这个在线压缩工具&#xff0c;点击进入后选择PDF压缩可以。如果需要手机和电脑端同步压…

react中Modal组件与openlayers地图实例化在feature要素绘制与清除等场景中存在的bug

在有地图的实际业务中会有一个经常的场景&#xff0c;那就是地图的初始化&#xff0c;一般如下&#xff1a; useEffect(() > {initMap();}, [visible]);我们经常利用Modal组件中open属性状态true与false来作为监听地图初始化的条件。 <Modaltitle{<div className"…

Python导入模块,Python import用法

使用 Python 进行编程时&#xff0c;有些功能没必须自己实现&#xff0c;可以借助 Python 现有的标准库或者其他人提供的第三方库。比如说&#xff0c;在前面章节中&#xff0c;我们使用了一些数学函数&#xff0c;例如余弦函数 cos()、绝对值函数 fabs() 等&#xff0c;它们位…

git修改历史提交(commit)信息

我们在开发中使用git经常会遇到想要修改之前commit的提交信息&#xff0c;这里记录下怎么使用git修改之前已经提交的信息。一、修改最近一次commit的信息 首先通过git log查看commit信息。 我这里一共有6次commit记录。 最新的commit信息为“Merge branch ‘master’ of https:…

在线研讨会邀请 | 赋能“大”研发,助力“快”交付

在全速前进的后疫情时代&#xff0c;公司业务飞速发展&#xff0c;您&#xff0c;准备好了吗—— 您的开发、设计、美术等团队可能分布在全球各地&#xff0c;您如何帮助他们实现跨部门、跨区域的协作——让他们便捷共享、审查各种大文件&#xff08;包括二进制文件&#xff0…

【GD32F427开发板试用】+ GDLink和USART2

本篇文章来自极术社区与兆易创新组织的GD32F427开发板评测活动&#xff0c;更多开发板试用活动请关注极术社区网站。作者&#xff1a;夏漳 一 GDLink下载和调试 1.1 硬件结构和试用板组成 感谢极术社区提供的GD32开发板&#xff0c;具体的板子资源和配套软件可以在极术社区官…

09笔记 IO操作

目录 一.向一个文本文件中写入数据&#xff1a; 二.从一个文本文件中读取数据&#xff0c;并对读取的数据做简单处理。 三.二进制文件的写入操作 四.对二进制文件的读取操作 五. 举例 六.IO操作的简单应用&#xff08;代码和举例都在更新和完善中&#xff09; 一.向一个文本…

软件测试工程师成神之路2023整理版

版本 更新日期 审核 备注 V0.3 2020-06-01 三丰 增加3大自动化 V1.0 2021-10-01 Nick 添加持续集成 V2.0 2023-01-31 三丰 完整性能版本 我看到迄今为止最完整的软件测试技术路线梳理 Python 编程语言 自动化之Python 编程语言 编程语言介绍/编程概念讲解/环…

大数据技术架构(组件)29——Spark:Memory Model(2)

2.1.8.5、Memory addressing以上小节介绍了spark对堆的划分&#xff0c;根据使用目的不同&#xff0c;对堆进行了区域划分,并说明了spark1.6之前和之后使用的两种不同内存模型管理以及之间的区别&#xff0c;那么这里继续逐步分析&#xff0c;说到内存管理&#xff0c;spark是如…

CTFshow菜狗杯-misc-wp(详解 脚本 过程 全)

首先感谢ctf平台和各位出题的大佬其次感谢各位读者&#xff0c;对我的支持( •̀ ω •́ )y 有什么问题和建议可以私聊我废话不多话开启你们的旅程吧 这个也是我这几天才看 一些见解和思路分享给你们希望你们在旅途中玩的开心&#xff0c;学的开心✌( •̀ ω •́ )y杂项签到…

opencv+python物体检测【03-模仿学习】

仿照练习&#xff1a;原文链接 步骤一&#xff1a;准备图片 正样本集&#xff1a;正样本集为包含“识别物体”的灰度图&#xff0c;一般大于等于2000张&#xff0c;尺寸不能太大&#xff0c;尺寸太大会导致训练时间过长。 负样本集&#xff1a;负样本集为不含“识别物体”的…

无公网IP环境快解析实现医美ERP外网访问

现阶段&#xff0c;借助医学手段让人们变美逐渐成为时尚&#xff0c;医美走进公众生活的步伐也在不停加快&#xff0c;整个医美行业总体处于蓬勃发展之势&#xff0c;因此医美行业ERP需求量也不断增加。医美管理软件系统涵盖HIS、进销存、CRM、CallCenter、经营报表等模块&…

【王道数据结构】第七章| 查找 | 树

目录 一、查找 1、查找概念 2、顺序查找 3、折半查找 4、分块查找 二、树 1、B树 2、B树的基本操作 3、B树 4、散列查找及其性能分析 5、散列查找及性能分析 一、查找 1、查找概念 查找&#xff1a;在数据集合中寻找满足某种条件的数据元素的过程称为查找。查找…

当ChatGPT遇到前端开发

目录 一、ChatGPT是什么&#xff1f; 二、怎么注册使用ChatGPT&#xff1f; 1、注册账号 2.完成 ChatGPT 手机号码验证 3、登录 ChatGPT 账号并开始使用 三、当ChatGPT遇到前端开发 四、深思总结 AIGC 作画带给人们的惊艳感觉还未散去&#xff0c;ChatGPT 又来刺激人类脆…