当前位置: 首页 > news >正文

[Qt][Qt 事件][下]详细讲解

目录

  • 1.定时器
    • 0.是什么?
    • 1.QTimerEvent
    • 2.QTimer
    • 3.获取系统⽇期及时间
  • 2.事件分发器
    • 1.概述
    • 2.事件分发器工作原理
    • 3.使用
  • 3.事件过滤器
    • 0.是什么?
    • 2.使用


1.定时器

0.是什么?

  • 在进⾏窗⼝程序的处理过程中,经常要周期性的执⾏某些操作,或者制作⼀些动画效果,使⽤定时器就可以实现
  • 定时器:就是在间隔⼀定时间后,去执⾏某⼀个任务
  • Qt中的定时器分为QTimerEventQTimer这2个类

1.QTimerEvent

  • QTimerEvent:⽤来描述⼀个定时器事件
  • 使用
    • startTimer():开启⼀个定时器
      • 参数:以毫秒为单位的整数作为参数来表明设定的时间
      • 返回值:一个整形的身份标识,代表这个定时器
    • 当定时器溢出时(即定时时间到达)就可以在timerEvent()中获取该定时器的编号来进⾏相关操作
    • killTimer:关闭定时器
  • 注意:如果一个程序中存在多个定时器(startTimer创建的定时器),此时每个定时器都会触发timerEvent()
  • 示例
    // 构造函数中
    {// 开启定时器事件.// 此处 timerId 是一个定时器的身份标识.timerId = this->startTimer(1000);
    }void Widget::timerEvent(QTimerEvent* event)
    {// 先判定一下这次触发是否是想要的定时器触发的.if (event->timerId() != this->timerId) {return;}int value = ui->lcdNumber->intValue();if (value <= 0) {// 停止定时器this->killTimer(this->timerId);return;}value -= 1;ui->lcdNumber->display(value);
    }
    

2.QTimer

  • QTimer底层是QTimerEvent
  • QTimer实现⼀个定时器,它提供了更⾼层次的编程接⼝
    • 如:可以使⽤信号和槽,还可以设置只运⾏⼀次的定时器
  • 示例
    QTimer* timer = new QTimer(this);connect(ui->btn1, &QPushButton::clicked, [=](){timer->start(1000);
    });connect(timer, &QTimer::timeout, [=](){static int num = 1;ui->label->setText(QString::number(num++));
    });connect(ui->btn2, &QPushButton::clicked, [=](){timer->stop();
    });
    

3.获取系统⽇期及时间

  • 在Qt中,获取系统的⽇期及实时时间可以通过QTimer类和QDateTime

  • QDateTime类提供了字符串格式的时间,输出格式由toString()⽅法中的format参数列表决定

    请添加图片描述

  • 示例

    // 构造函数中
    {QTimer* timer = new QTimer(this);connect(ui->btn1, &QPushButton::clicked, [=](){timer->start(1000);});connect(ui->btn2, &QPushButton::clicked, [=](){timer->stop();});connect(timer, &QTimer::timeout, this, &Widget::TimeUpdate);
    }void Widget::TimeUpdate()
    {QString t = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");ui->label->setText(t);
    }
    

2.事件分发器

1.概述

  • 在Qt中,事件分发器(EventDispatcher)是⼀个核⼼概念,⽤于处理GUI应⽤程序中的事件
    • 属于Qt事件机制背后的一些逻辑
    • 杀伤力比较广,不当使用可能对现有逻辑造成一些负面影响,一般不建议使用
  • 事件分发器负责将事件从⼀个对象传递到另⼀个对象,直到事件被处理或被取消
  • 每个继承⾃QObject类或QObject类本⾝都可以在本类中重写bool event(QEvent* e),来实现相关事件的捕获和拦截

2.事件分发器工作原理

  • 在Qt中,发送的事件都是传给了QObject对象,更具体点是传给了QObject对象的event()
    • 所有的事件都会进⼊到这个函数⾥⾯
      • 那么处理事件就要重写这个event()函数
    • event()函数本⾝不会去处理事件,⽽是根据事件类型(type)调⽤不同的事件处理函数
  • 事件分发器就是⼯作在应⽤程序向下分发事件的过程中
    • 事件分发器⽤于分发事件,在此过程中,事件分发器也可以做拦截操作
    • 事件分发器主要是通过bool event(QEvent* e)来实现
      • 返回值:若为ture,代表拦截,不向下分发
        请添加图片描述

3.使用

  • Qt中的事件是封装在QEvent类中,其所包括的事件类型:

    请添加图片描述

  • 示例:拦截鼠标左键单击事件

    void Widget::mousePressEvent(QMouseEvent* event)
    {if(event->button() == Qt::LeftButton){qDebug() << "鼠标左键被按下";}
    }bool Widget::event(QEvent* ev)
    {if(ev->type() == QEvent::MouseButtonPress){qDebug() << "Event中鼠标被按下";return true; // 返回true,代表拦截,不向下分发}// 其他事件交给父类处理(默认处理)return QWidget::event(ev);
    }
    

3.事件过滤器

0.是什么?

  • 在Qt中,⼀个对象可能经常要查看或拦截另外⼀个对象的事件
    • 例如:对话框想要拦截按键事件,不让别的组件接收到,或者修改按键的默认值等
    • 属于Qt事件机制背后的一些逻辑
    • 杀伤力比较广,不当使用可能对现有逻辑造成一些负面影响,一般不建议使用
  • Qt创建了QEvent事件对象之后,会调⽤QObjectevent()函数处理事件的分发,可以在event()函数中实现拦截的操作
    • 由于event()protected的,因此,需要继承已有类
    • 如果组件很多,就需要重写很多个event()
      • 这当然相当⿇烦,更不⽤说重写event()还得⼩⼼⼀堆问题
      • 好在Qt提供了另外⼀种机制来达到这⼀⽬的:事件过滤器
  • 事件过滤器是在应⽤程序分发到event事件分发器之前,再做⼀次更⾼级的拦截
    请添加图片描述

2.使用

  • 事件过滤器的⼀般使⽤步骤
    • 安装事件过滤器
    • 重写事件过滤器函数:eventfilter()
  • 示例
    {void MyLabel::mousePressEvent(QMouseEvent* event){QString str = QString("鼠标按下: x = %1, y = %2").arg(event->x()).arg(event->y());qDebug() << str.toUtf8().data();}void MyLabel::event(QEvent* ev){if(ev->type() == QEvent::MouseButtonPress){QMouseEvent* event = static_cast<QMouseEvent* e>(e);QString str = QString("event中鼠标按下: x = %1, y = %2").arg(event->x()).arg(event->y());qDebug() << str.toUtf8().data();return true; // 返回true,代表拦截,不向下分发}// 其他事件交给父类处理(默认处理)return QWidget::event(ev);}
    }
    ----------------------------------------------------------------------
    {// Widget构造函数中{// 步骤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>(e);QString str = QString("事件过滤器中鼠标按下: x = %1, y = %2").arg(event->x()).arg(event->y());qDebug() << str.toUtf8().data();return true;}}// 其他事件交给父类处理return QWidget::event(ev);}
    }
    

相关文章:

[Qt][Qt 事件][下]详细讲解

目录 1.定时器0.是什么&#xff1f;1.QTimerEvent2.QTimer3.获取系统⽇期及时间 2.事件分发器1.概述2.事件分发器工作原理3.使用 3.事件过滤器0.是什么&#xff1f;2.使用 1.定时器 0.是什么&#xff1f; 在进⾏窗⼝程序的处理过程中&#xff0c;经常要周期性的执⾏某些操作&…...

八股总结----计算机网络

0.OSI七层模型 自己的理解&#xff1a;应用层&#xff1a;生成HTTP请求报文-----表示层&#xff1a;将请求报文转换成适合网络传输的数据格式&#xff0c;加密压缩编码等-----会话层&#xff1a;管理两个应用程序之间的会话&#xff0c;包括连接中断等------传输层&#xff1a…...

Laravel 框架开发 ERP 系统,技术选型和分析以及实施计划

目录 技术选型 技术分析 实施计划 实施步骤 可能需要引入的组件包 技术难点及解决方案 基于 Laravel 框架开发 ERP 系统&#xff0c;技术选型和分析以及实施计划需要考虑多个方面&#xff1a; 技术选型 后端框架&#xff1a;Laravel&#xff0c;因为它提供了丰富的功能…...

【Vue3】嵌套路由

【Vue3】嵌套路由 背景简介开发环境开发步骤及源码 背景 随着年龄的增长&#xff0c;很多曾经烂熟于心的技术原理已被岁月摩擦得愈发模糊起来&#xff0c;技术出身的人总是很难放下一些执念&#xff0c;遂将这些知识整理成文&#xff0c;以纪念曾经努力学习奋斗的日子。本文内…...

pygame小游戏

代码存在一些bug&#xff0c;感兴趣可自行修改&#xff0c;游戏运行后玩法与吃金币游戏类似。&#xff08;代码及结果比较粗糙&#xff0c;仅供参考&#xff09; 注&#xff1a;&#xff08;图片、音乐、音效文件老是上传上传不上&#xff0c;想要可私&#xff0c;也可以自己找…...

.Net Core IIS 程序报错 Access to the path c:\\windows\\TEMP\\poifiles is denied

程序运行报错&#xff1a;Access to the path c:\\windows\\TEMP\\poifiles is denied &#xff0c;此错误本文介绍两种解决办法&#xff0c;选择适合你的方法即可&#xff1b;一般.Net程序运行方案二可能比较常用。 解决方案一&#xff1a; 从 IIS 访问文件系统 如果您在浏…...

交换机VLAN配置中Tagged与Untagged端口的差异和应用区别

VLAN&#xff08;虚拟局域网&#xff09;是一种将局域网设备从逻辑上划分为不同虚拟工作组的技术。它打破了传统局域网在物理位置上的限制&#xff0c;允许网络管理员根据功能、部门或安全需求等因素&#xff0c;将同一物理网络中的设备划分到不同的逻辑网络中。每个VLAN都像一…...

@OneToOne注解的作用

OneToOne 注解在 Java Persistence API (JPA) 中用于定义实体之间的一对一关系。这种关系意味着两个实体之间通过一个唯一键相互关联&#xff0c;即一个实体中的一个字段&#xff08;通常是主键或唯一字段&#xff09;对应于另一个实体中的一个字段&#xff08;也可以是主键或唯…...

vue动画、过渡效果

vue动画、过渡效果 一.动画二.过渡三.多个元素过渡四.第三方库的使用五.总结 一.动画 1.默认.v-enter-active/.v-leave-active, 如果有name则.name-enter-active/.name-leave-active 2.appear意思是一打开页面就 实现动画&#xff0c;是appear"true"的简写 二.过渡 三…...

在 Vue 3 项目中使用 Element UI Plus <el-calendar>组件与时区处理

文章目录 前言简介<el-calendar> 组件组件定制基础自定义内容示例优化点 时区处理时区问题简介获取时区偏移量 下期扩展&#xff1a;自己实现一个<el-calendar> 的思路结语 前言 简介 在 Vue 3 项目开发过程中&#xff0c;我们经常需要对 UI 组件进行定制以满足特…...

【系统架构设计】计算机网络

【系统架构设计】计算机网络 网络架构与协议网络互联模型OSI/RM 结构模型TCP/IP结构模型IPv6 局域网与广域网局域网特点 网络互连与常用设备网络互联设备交换技术路由技术 网络存储技术 网络架构与协议 网络互联模型 OSI/RM 结构模型 1977年&#xff0c;国际标准化组织为适应…...

《中国数据库前世今生》——历史的深度与未来的展望

在探索科技与历史的交织中&#xff0c;我有幸观看了《中国数据库前世今生》这部纪录片。影片开头它不仅是一段技术演进的回顾&#xff0c;更是中国IT领域从跟随到引领的壮丽史诗。后续深刻研读了专家们的深刻讨论&#xff0c;通过这部纪录片&#xff0c;我深刻感受到了数据库技…...

web前端之实现霓虹灯背景魔术卡、旋转的背景动画、模糊效果、边框、变量、filter

MENU 前言效果图htmlstyle 前言 代码段定义一个名为Magic Card的卡片&#xff0c;并通过一系列CSS属性和动画效果来美化和增强该卡片的视觉效果。 效果图 html <div class"card">Magic Card </div>style 代码 property --rotate {syntax: "<a…...

几款免费的时序数据库对比

InfluxDB、TDengine、OpenTSDB、QuestDB都是当前主流的时序数据库&#xff0c;它们在性能、功能、适用场景等方面各有特点。下面将从多个维度对这四个数据库进行对比分析&#xff1a; 一、性能 InfluxDB&#xff1a; 高效的时间序列数据写入性能&#xff0c;自定义TSM引擎&am…...

基于springboot的乐享田园系统

TOC springboot181基于springboot的乐享田园系统 第1章 绪论** 1.1 课题背景 二十一世纪互联网的出现&#xff0c;改变了几千年以来人们的生活&#xff0c;不仅仅是生活物资的丰富&#xff0c;还有精神层次的丰富。在互联网诞生之前&#xff0c;地域位置往往是人们思想上不…...

深入解析Objective-C中NSParagraphStyle的段落样式处理艺术

标题&#xff1a;深入解析Objective-C中NSParagraphStyle的段落样式处理艺术 在Objective-C的世界中&#xff0c;文本排版是一个复杂但至关重要的话题。NSParagraphStyle作为其中的核心组件&#xff0c;扮演着决定文本段落外观和布局的关键角色。本文将深入探讨NSParagraphSty…...

Qt编程技巧小知识点(2)GPIB缓存区数据读取

文章目录 Qt编程技巧小知识点&#xff08;2&#xff09;GPIB缓存区数据读取小结 Qt编程技巧小知识点&#xff08;2&#xff09;GPIB缓存区数据读取 大端小端的问题&#xff0c;其主要表现如下例子&#xff1a; 例如&#xff1a;输入为QByteArray str "#14M\xB6q\xC1\n&qu…...

数的个位相加

给定一个非负整数 num&#xff0c;反复将各个位上的数字相加&#xff0c;直到结果为一位数。返回这个结果。 示例 1: 输入: num 38输出: 2 解释: 各位相加的过程为&#xff1a; 38 --> 3 8 --> 11 11 --> 1 1 --> 2 由于 2 是一位数&#xff0c;所以返回 2。…...

专业技能(挖坑填坑)——MYSQL的索引、日志、事务、存储引擎、锁机制等相关原理

熟悉MySQL的使用&#xff0c;熟悉MYSQL的索引、日志、事务、存储引擎、锁机制等相关原理。 1.mysql索引&#xff0c;索引的底层数据结构实现 索引就是目录可以帮助快速的找到对应的资源。 MySQL默认的InnoDB存储引擎使用的索引底层数据结构是BTree。BTree是一种多路搜索查找树…...

C++(27): 线程池

目录 1. 概述 2. 例程 &#xff08;1&#xff09;ThreadPool.h &#xff08;2&#xff09;ThreadPool.cpp &#xff08;3&#xff09;Start.cpp &#xff08;4&#xff09;编译 1. 概述 线程池技术绝不是C独有的&#xff0c;Java和Python都有比较晚完善的线程池构造接口…...

每日一题-贪心算法

122. 买卖股票的最佳时机 II - 力扣&#xff08;LeetCode&#xff09; 55. 跳跃游戏 - 力扣&#xff08;LeetCode&#xff09; 这个题目一开始肯定是会懵&#xff0c;就比如说一开始先跳几步&#xff0c;之后再怎么跳&#xff0c;其实我们就可以用最大范围来算就行了&#xff0…...

PSO 算法实例(手动推导过程)

PSO 算法实例 引言正文PSO 算法步骤PSO 实例步骤1 定义目标函数步骤2 初始化每个粒子的位置和速度步骤3 使用目标函数进行评估步骤4 更新单个粒子的最佳位置(局部最优值)步骤5 更新全局最佳位置(全局最优值)步骤6 更新每个粒子的位置和速度步骤7 使用目标函数评估新的位置步…...

解决antd TreeSelect 返回值不包含父节点问题 -自定义组件(react)

在写一个表单时使用了antd的 TreeSelect&#xff0c;在对TreeSelect的值提交时发现&#xff0c;父节点的值在半选状态时未提交&#xff0c;在选中状态时&#xff08;子节点全选&#xff09;&#xff0c;子节点不提交&#xff0c;只提交父节点&#xff0c;这与后端需求不符&…...

花四小时,写了个在线实时绘制等值面图小软件,明晚上线,喜欢的小伙伴关注哦

科研党的福音&#xff0c;绘图再也不需要安装一堆软件了&#xff0c;可以在线绘图了&#xff1b; 只需要传入绘制的区间、色值、以及所需要绘制的数据就可以直接出图了&#xff0c;可绘制各种等值面图&#xff0c;比如降水分布&#xff0c;高温分布&#xff0c;人口分布&#x…...

c++的vector用法

文章目录 1. 创建和初始化 std::vector2. 添加和删除元素3. 访问和遍历元素4. std::vector 的其他常用操作 std::vector 是 C 标准库中的一个动态数组容器&#xff0c;提供了灵活的存储和访问功能。 1. 创建和初始化 std::vector #include <iostream> #include <vect…...

【Linux网络】Linux网络初探:开启网络世界的大门

W...Y的主页 &#x1f60a; 代码仓库分享&#x1f495; 前言&#xff1a;我们已经系统的学习了Linux的基本操作、进程、线程、文件、通信等待&#xff0c;但是在如今社会没有网络通信方式是万万不行的&#xff0c;今天我们就走进网络中&#xff0c;系统的学习一下有关Linux网…...

目录、用户与组、出错相关函数、时间函数

一、目录相关函数及属性 1、 opendir()函数 opendir 用于打开一个目录&#xff0c;并返回一个目录流指针。name&#xff1a;要打开的目录的路径。 返回值&#xff1a;成功时返回指向目录流的指针&#xff0c;失败时返回 NULL。 #include <dirent.h> DIR *opendir(con…...

<keep-alive> 一分钟了解

<keep-alive> 一分钟了解 <keep-alive> 是 Vue.js 提供的一个抽象组件&#xff0c;它的主要用途是在页面或组件切换时保留其状态&#xff0c;避免重复执行昂贵的渲染操作&#xff0c;从而提升应用性能。 文章目录 <keep-alive> 一分钟了解 一、 <keep-ali…...

Android 启动动画太生硬

跟 android:launchMode"singleTask"属性无关系 请禁用路由 ARouter.getInstance() .build(Routes.Main.MAIN) .withTransition(R.anim.activity_anim_in, R.anim.activity_anim_out).navigation() 正确做法是 val intent Intent(thisSplashActivity,MainActivit…...

深度学习中常用概念总结

最近在做深度学习&#xff0c;里面涉及到很多概念&#xff0c;有的名称都差不多容易记混。所以写这篇文章总结一下。眼过千遍不如手过一遍。 1. 轮数&#xff08;Epochs&#xff09;: 一轮&#xff08;Epoch&#xff09;指的是整个训练数据集在训练过程中被完整使用一次。…...