Qt 实战(6)事件 | 6.1、事件机制

文章目录

  • 一、事件
    • 1、基本概念
    • 2、事件描述
    • 3、事件循环
    • 4、事件分发
      • 4.1、QApplication::notify()
      • 4.2、QObject::event()
    • 5、事件传递
    • 6、事件处理器

前言:

Qt 框架中的事件机制(Event Mechanism)是一种核心功能,它允许应用程序以事件驱动的方式响应各种外部和内部发生的动作。事件机制在 Qt 中扮演着至关重要的角色,无论是在用户界面的交互还是在后台处理数据时。它不仅确保了程序的响应性和灵活性,还大大降低了编程的复杂性,使开发者能够以更直观的方式来处理异步事件。

一、事件

1、基本概念

事件是由程序的内部或外部产生的事情或某种操作的统称。例如:用户按下鼠标或键盘就会产生一个鼠标或键盘事件,当窗口第一次绘制时会产生一个绘制事件。Qt中的事件主要来源于以下几个方面:

  • 用户输入:如鼠标点击、键盘按键、触摸屏操作等。
  • 系统事件:如窗口大小改变、系统时间变化、网络状态改变等。
  • 定时器事件:通过QTimer类创建的定时器事件。
  • 其他事件:如自定义事件、信号与槽机制触发的事件等

事件的作用:事件在 Qt 应用程序中扮演着至关重要的角色。它们是应用程序与用户或系统交互的基础,使得程序能够以非阻塞的方式响应外部的变化。通过事件,Qt 应用程序能够保持响应性和灵活性,同时简化复杂交互的处理逻辑。

2、事件描述

在Qt中使用抽象类QEvent类来描述事件,所有事件都是QEvent的派生类。基本的QEvent类只包含一个事件类型参数,QEvent的子类包含额外的参数用来描述事件信息。事件类型使用QEvent::type来表示,这个枚举类定义了Qt中有效的事件类型。Qt中常见的事件有

  • 键盘事件(QKeyEvent)
  • 鼠标事件(QMouseEvent)
  • 拖放事件(QDragEvent 和 QDropEvent)
  • 绘图事件(QPaintEvent)
  • 焦点事件(QFocusEvent)

3、事件循环

通过QApplication::exec() 开启事件循环,事件循环运行在一个无限循环中,不断检查是否有新的事件发生。当事件发生时,它们被加入到一个队列中。事件循环按照事件发生的顺序,从队列中取出并分发这些事件到相应的对象进行处理。这个过程是异步的,意味着事件的产生和处理是分离的,确保了应用程序的高效运行。事件循环是保持 Qt 应用程序响应性的关键。没有事件循环,应用程序将无法适时地响应用户输入、网络通信等事件。

在这里插入图片描述

4、事件分发

4.1、QApplication::notify()

在 Qt 的事件系统中,所有的事件(如鼠标点击、键盘输入、定时器事件等)都会经过 notify 方法进行分发。notify 方法原型如下:

bool notify(QObject *, QEvent *) Q_DECL_OVERRIDE;

默认情况下,notify 方法会调用相应对象(接受事件的对象)的 QObject::event 方法来处理这些事件。但可以通过重写 notify 方法来定制事件的处理方式。具体来说,QApplication::notify 的作用包括:

  • 事件分发:当 Qt 检测到一个事件(如鼠标点击、键盘输入等)时,它会调用 QApplication 的 notify 方法来分发这个事件。
  • 事件过滤:在事件被发送到目标对象之前,你可以通过重写 notify 方法来过滤或修改事件。例如,你可以阻止某个特定类型的事件被发送到某个对象。

一般来说,直接重写 QApplication 的 notify 方法并不常见,因为这样做会影响整个应用程序的事件处理。但在某些特殊情况下,如实现全局的事件过滤器或自定义事件分发策略时,重写 notify 方法可能会非常有用。

4.2、QObject::event()

QObject::event 在 Qt 框架中是一个重要的成员函数,用于处理接收到的 QEvent 对象,并将这些事件按照不同的类型,分发给不同的事件处理器。Qt中QObject::event的源码如下:

bool QObject::event(QEvent *e)
{
    switch (e->type()) {
    case QEvent::Timer:
        timerEvent((QTimerEvent*)e);
        break;

    case QEvent::ChildAdded:
    case QEvent::ChildPolished:
    case QEvent::ChildRemoved:
        childEvent((QChildEvent*)e);
        break;
    // ...
    default:
        if (e->type() >= QEvent::User) {
            customEvent(e);
            break;
        }
        return false;
    }
    return true;
}

5、事件传递

如果对象没有处理该事件(即没有重写对应的事件处理函数或函数中没有调用event->accept()),Qt会尝试将该事件传递给其父对象。这个过程会一直持续到某个对象处理了事件或事件到达了顶级对象(如应用程序窗口)为止。这就是所谓的“事件冒泡”(event bubbling)。

6、事件处理器

如果Qt找到了一个与事件相关的对象,它会调用该对象的事件处理器(也称为事件处理函数),这些事件处理器都是虚函数,直接重写对应的虚函数就可以处理自己的业务。下面是常见的事件及事件处理器,如下:

  • 鼠标事件(QMouseEvent)
    • mousePressEvent(QMouseEvent *event): 处理鼠标按键的按下事件
    • mouseReleaseEvent(QMouseEvent *event): 处理鼠标按键的释放事件。
    • mouseMoveEvent(QMouseEvent *event): 处理鼠标移动事件。
    • wheelEvent(QWheelEvent *event): 处理鼠标滚轮的滚动事件。
  • 键盘事件(QKeyEvent)
    • keyPressEvent(QKeyEvent *event): 处理键盘按键的按下事件。
    • keyReleaseEvent(QKeyEvent *event): 处理键盘按键的释放事件。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Launcher3】解决谷歌桌面的小部件重启后消失问题

1-问题摘要 这次主要解决困扰了我很久的时钟消失问题,大概是去年10月刚开始做EDLA项目的时候,需要定制谷歌桌面,桌面布局大概要改成这样: 时间显示在谷歌搜索框的上方,而安卓原生桌面大概是这样子的 我们开发一开始是使用小部件…

微服务+云原生:打造高效、灵活的分布式系统

🐇明明跟你说过:个人主页 🏅个人专栏:《未来已来:云原生之旅》🏅 🔖行路有良友,便是天堂🔖 目录 一、引言 1、云原生概述 2、微服务概述 二、微服务架构基础 1、…

二、反应式集成-spring

一、Spring WebFlux what 1、简介 - Spring WebFlux 包含一个用于执行 HTTP 请求的客户端。 有一个 基于 Reactor 的功能性、流畅的 API,请参阅 Reactive Libraries, 它支持异步逻辑的声明性组合,而无需处理 线程或并发。它是完全无阻塞的…

Talking Web

1. curl 1.1 http curl http://127.0.0.1:80 向目标主机端口发送http请求 1.2 httphead curl -H “Host: 18ed3df584cd48328b5839443aa7b42b” http://127.0.0.1:80 1.3 httppath curl http://127.0.0.1:80/853c64cd218f80d0a59665666fb2ab80 1.4 URL编码路径 &#xff0…

Python学习笔记21:进阶篇(十)常见标准库使用之math模块,random模块和statistics模块

前言 本文是根据python官方教程中标准库模块的介绍,自己查询资料并整理,编写代码示例做出的学习笔记。 根据模块知识,一次讲解单个或者多个模块的内容。 教程链接:https://docs.python.org/zh-cn/3/tutorial/index.html 数学 P…

微软结束将数据中心置于海底的实验

2016 年,微软 宣布了一项名为"纳蒂克项目"(Project Natick)的实验。基本而言,该项目旨在了解数据中心能否在海洋水下安装和运行。经过多次较小规模的测试运行后,该公司于 2018 年春季在苏格兰海岸外 117 英尺…

从0开始C++(八):多态的实现

相关文章: 从0开始C(一):从C到C 从0开始C(二):类、对象、封装 从0开始C(三):构造函数与析构函数详解 从0开始C(四):作…

React+TS前台项目实战(十九)-- 全局Input组件封装:加载状态和清除功能的实现

文章目录 前言Input组件1. 功能分析2. 代码详细注释3. 使用方式4. 效果展示 总结 前言 今天我们来封装一个input输入框组件,并提供一些常用的功能,你可以选择不同的 尺寸、添加前缀、显示加载状态、触发回调函数、自定义样式 等等。这些功能在这个项目中…

vite+vue3+ts项目搭建流程 (pnpm, eslint, prettier, stylint, husky,commitlint )

vitevue3ts项目搭建 项目搭建项目目录结构 项目配置自动打开项目eslint①vue3环境代码校验插件②修改.eslintrc.cjs配置文件③.eslintignore忽略文件④运行脚本 prettier①安装依赖包②.prettierrc添加规则③.prettierignore忽略文件④运行脚本 stylint①.stylelintrc.cjs配置文…

【云原生】Kubernetes网络知识

Kubernetes网络管理 文章目录 Kubernetes网络管理一、案例概述二、案例前置知识点2.1、Kubernetes网络模型2.2、Docker网络基础2.3、Kubernetes网络通信2.3.1、Pod内容器与内容之间的通信2.3.2、Pod与Pod之间的通信 2.4、Flannel网络插件2.5、Calico网络插件2.5.1、Calico网络模…

免费下载电子书的网站

在如今的数字化时代,电子书已成为许多人书籍阅读的首选。下面小编就和大家分享一些提供免费查找下载电子书服务的网站,这些网站不仅资源丰富,而且操作简便。 免费下载电子书的网站:https://www.bgrdh.com/favorites/1355.html 1…

数据可视化期末考试(编程)

1.KNN 1.新增数据的分类 import pandas as pd # 您的原始数据字典 data { 电影名称: [电影1, 电影2, 电影3, 电影4, 电影5], 打斗镜头: [10, 5, 108, 115, 20], 接吻镜头: [110, 89, 5, 8, 200], 电影类型: [爱情片, 爱情片, 动作片, 动作片, 爱情片] } …

昇思25天学习打卡营第8天 | 模型的保存与加载

内容介绍:在训练网络模型的过程中,实际上我们希望保存中间和最后的结果,用于微调(fine-tune)和后续的模型推理与部署,本章节我们将介绍如何保存与加载模型。 具体内容: 1. 导包 import numpy…

1.1 MySQL用户管理

1.1.1 用户的定义 用户名主机域 mysql> select user,host,password from mysql.user; --------------------------------------------------------------- | user | host | password | -----------------------------------------…

el-form重置后input无法输入问题

新增用户遇到的问题: 如果你没有为 formData 设置默认值,而只是将其初始化为空对象 {},则在打开dialog时,正常输入, formdata会变成如下 但是,打开后,直接使用 resetFields 或直接清空表单&…

LLDB 详解

LLDB 详解 LLDB 详解编译器集成优势LLDB 的主要功能命令格式原始(raw)命令选项终止符: -- LLDB 中的变量唯一匹配原则helpexpressionprint、call、po控制流程:continue、next、step、finishregister read / writethread backtracethread retu…

基于weixin小程序新生报到系统的设计

管理员账户功能包括:系统首页,个人中心,学生管理,班级信息管理,师资力量管理,宿舍信息管理,宿舍安排管理,签到信息管理,论坛管理 小程序功能包括:系统首页&am…

考研数学一有多难?130+背后的残酷真相

考研数学一很难 大家平时在网上上看到很多人说自己考了130,其实这些人只占参加考研数学人数的极少部分,有个数据可以展示出来考研数学到底有多难: 在几百万考研大军中,能考到120分以上的考生只有2%。绝大多数人的分数集中在30到…

【MySQL进阶之路 | 高级篇】MySQL8.0索引新特性->降序索引与隐藏索引

1. 支持降序索引 降序索引以降序存储键值.虽然在语法上,从MySQL4版本已经支持降序索引的语法了,但实际上该DESC定义是被忽略的.知道MySQL8.x版本才开始真正支持降序索引.(仅限于InnoDB存储引擎). MySQL在8.0版本前创建的仍然是升序索引,使用…

【C++11(二)】lambda表达式和可变参数模板

一、可变参数模板 C11的新特性可变参数模板 能够让您创建可以接受 可变参数的函数模板和类模板 // Args是一个模板参数包&#xff0c;args是一个函数形参参数包 // 声明一个参数包Args...args&#xff0c;这个参数包中可以包含0到任意个模板参数。 template <class ...Arg…