【快速上手QT】04-定时器Timer

先来个小示例

我们先简单的来触发一下定时器。

#include "Zhetu.h"#include <qdebug.h>void Zhetu::timerEvent(QTimerEvent* event) {	//定时器触发函数qDebug() << "Hello world";
}Zhetu::Zhetu(QWidget *parent): QMainWindow(parent){this->setFixedSize(500, 500);this->startTimer(1000);			//开启以1000ms为周期的定时器
}

上面的代码很简单,就是开启一个1000ms的定时器,定时器触发的时候调用timerEvent这个函数,并且输出调试信息“Hello world”。

这边有几个需要注意的点,就是定时器触发函数是固定的,就是要下面这个形式。

void timerEvent(QTimerEvent* event)

当然,形参的名字可以自己起,但是返回值,函数名,形参类型都是需要固定的。

并且我们能够看得出来,开启定时器的对象是我们的主界面(在主界面的构造函数中)。因此我们的定时器触发函数得是我们主界面这个类的成员函数。

startTimer

我们使用startTimer这个函数就使得我们的主界面调用了定时器,那么我是怎么知道用这个函数的呢?答案就是QT助手。

我们的主界面类继承的是QMainWindow这个类,那么我们就去搜索QMainWindow,我们去找有没有定时器相关的函数,答案是没有的。

既然QMainWindow没有,那么我们就去它的父类去找。

然而我们在它的父类里也找不到,那么我们再从QWidget的父类中去寻找。

QWidget的父类有两个,分别是QObject和QPaintDevice。

凭借我高超的英语水平(四级差122分),一眼就能看出我们需要从QObject里找,因为QPaintDevice根据直译来判断,应该是和图形化相关的。

果然我们能在QObject中找到相关函数。

当我们点击进去之后就能看到关于这个函数的详细的解释了。

凭借我高超的英语水平(四级差122分),一眼就能看出我看不懂,所以我们稍微翻译参考一下。

根据这个粗糙的翻译,我们可以知道调用这个函数之后会返回一个标识符(ID),并且定时器事件会在每个时间间隔触发,直到我们调用killTimer这个函数,很明显这个函数是用来杀死(kill)定时器事件的。

我们再次点击进入killTimer这个函数。

我们知道startTimer会返回一个定时器ID,那么我们取消定时器,使用killTimer用的参数也是这个ID。

再回到我们的startTimer函数的解释里。

定时器事件触发之后,会调用TimerEvent函数。如果有多个定时器函数,我们还可以通过TimerEvent的参数去调用timerId来获取当前触发定时器函数的定时器ID是什么。

综上我们可以知道以下几个关键的信息。

  • startTimer是QObject的函数,而大多数组件都直接或间接继承了QObject,所以大多数组件都可以开启定时器。
  •  我们可以通过调用startTimer获取的定时器ID来删除定时器事件或是判断触发定时器事件的是哪个ID
  • 同类组件哪怕开启了多个定时器,但是定时器触发函数是固定的一个。

这样我们大概知道了怎么通过OBject的成员函数来开启定时器事件之后,我们就可以来测试一下了。

#include "Zhetu.h"#include <qdebug.h>
#include <qpushbutton.h>int windowID, buttonID;void Zhetu::timerEvent(QTimerEvent* event) {	//定时器触发函数static int count = 0;if (event->timerId() == windowID) {		//获取触发定时器的ID,比较是否是主界面的定时器IDqDebug() << "w";if (++count >= 10) {killTimer(windowID);			//取消主界面定时器qDebug() << "kill window timer";}}
}void QAbstractButton::timerEvent(QTimerEvent* event){static int count = 0;if (event->timerId() == buttonID) {		//获取触发定时器的ID,比较是否是按键的定时器IDqDebug() << "b";if (++count >= 10) {killTimer(buttonID);			//取消按键定时器qDebug() << "kill button timer";}}
}Zhetu::Zhetu(QWidget *parent): QMainWindow(parent){this->setFixedSize(500, 500);QPushButton* button = new QPushButton("Timer", this);buttonID = button->startTimer(500);			//开启以500ms为周期的定时器windowID = this->startTimer(1000);			//开启以1000ms为周期的定时器
}

上面代码中,我用主界面开启了一个定时器,用一个普通的按键也开启了一个定时器。

由于它们所属的类不一样,因此需要重写两次TimerEvent函数。并且它们所属的类需要区分来开。

主界面的定时器触发函数的所属类就写Zhetu(我写的主界面类的名称)。

而按键的定时器触发函数的所属类需要写QAbstractButton,如果写QPushButton的话是不允许的,我已经试过了。

在各自的定时器触发函数中我通过调用参数的timerId来获取触发定时器事件的ID进行定时器ID的判断,各自触发十次之后取消定时器事件。

从下面运行结果的截图中也可以看的出来是没问题的。

QTimer

上面的开启定时器其实是够用了,不过这里还是介绍一下QTimer这个类,因为这个类才算得上是真正的定时器。

与startTimer不同的是,Timer开启定时器的方式是信号与槽函数。

我们照例先来个小例子。

#include "Zhetu.h"#include <qdebug.h>
#include <QTimer> Zhetu::Zhetu(QWidget *parent): QMainWindow(parent){this->setFixedSize(500, 500);QTimer* t1 = new QTimer(this);connect(t1, &QTimer::timeout, [&]() {qDebug() << "hello world";});t1->start(1000);
}

既然触发定时器事件的是信号和槽函数,那么我们先看看QTimer都有些什么信号和槽函数。

看得出来信号只有一个,那就是timeout,凭借我高超的英语水平(四级差122分),一眼就能看出这个信号就是定时器定的时间到了之后发出的信号,也就是是计数溢出信号。

我们将这个信号和自定义的定时器触发函数进行绑定(connect),就可以达到触发定时器事件的目的了。

而我们可以调动槽函数去控制这个定时器 。

很明显start就是开启定时器,而stop就是关闭定时器。

那么我们通过上面一个小例子就可以知道如何使用Timer来实现定时器的周期计数了。

这边再介绍一个非周期计数,也就是只触发一次定时器事件的函数。

#include "Zhetu.h"#include <qdebug.h>
#include <QTimer> Zhetu::Zhetu(QWidget *parent): QMainWindow(parent){this->setFixedSize(500, 500);QTimer* t1 = new QTimer(this);t1->singleShot(1000, []() {qDebug() << "Hello";});
}Zhetu::~Zhetu()
{}

虽然我们使用周期定时器也可以达到同样的效果(触发一次之后就关闭周期定时器),但是这个非周期的定时器有一个特点,那就是它属于静态成员函数,也就是说我们不需要创建QTimer对象就可以使用这个函数。

这也是这个函数比较方便的一点。

QTimer::singleShot(1000, []() {qDebug() << "helo world";});

小结

关于定时器的使用我这里只是介绍了一点,但是对于我们需要快速上手的小伙伴来说是够用了,想要更近一步的小伙伴可以自己去查阅资料以及QT助手去自主进阶学习。

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

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

相关文章

C#,数值计算,矩阵的乔莱斯基分解(Cholesky decomposition)算法与源代码

一、安德烈路易斯乔尔斯基 安德烈路易斯乔尔斯基出生于法国波尔多以北的查伦特斯海域的蒙古扬。他在波尔多参加了Lyce e&#xff0c;并于1892年11月14日获得学士学位的第一部分&#xff0c;于1893年7月24日获得第二部分。1895年10月15日&#xff0c;乔尔斯基进入莱科尔理工学院…

PhotoSweeper X mac版 v4.8.5 相似重复照片清理工具 兼容 M1/M2

PhotoSweeper X for Mac是一款Mac重复照片/相似照片清理工具&#xff01;PhotoSweeper可以帮你进行&#xff1a;重复相似照片/数码相片查找、对比和删除&#xff0c;轻松清理Mac上的重复图片&#xff0c;非常实用。 应用介绍 PhotoSweeper X for Mac是一款Mac重复照片/相似照片…

实战打靶集锦-025-HackInOS

文章目录 1. 主机发现2. 端口扫描3. 服务枚举4. 服务探查5. 提权5.1 枚举系统信息5.2 探索一下passwd5.3 枚举可执行文件5.4 查看capabilities位5.5 目录探索5.6 枚举定时任务5.7 Linpeas提权 靶机地址&#xff1a;https://download.vulnhub.com/hackinos/HackInOS.ova 1. 主机…

【图片公式识别】图片公式转Word与LaTeX文档:智能识别与转换

前言 嘿&#xff0c;大家好呀&#xff01;&#x1f44b; 谁都知道&#xff0c;写 Word 文档里的公式可不是一件简单的事情&#xff01;你辛辛苦苦在键盘上敲出的数学公式&#xff0c;结果随着 Word 版本的更新&#xff0c;竟然变成了一张图片&#xff01;&#x1f624; 这简直就…

板块一 Servlet编程:第八节 文件上传下载操作 来自【汤米尼克的JavaEE全套教程专栏】

板块一 Servlet编程&#xff1a;第八节 文件的上传下载操作 一、文件上传&#xff08;1&#xff09;前端内容&#xff08;2&#xff09;后端内容 二、文件下载&#xff08;1&#xff09;前端的超链接下载&#xff08;2&#xff09;后端下载 在之前的内容中我们终于结束了Servle…

qtday2作业

思维导图 使用手动连接&#xff0c;将登录框中的取消按钮使用qt4版本的连接到自定义的槽函数中&#xff0c;在自定义的槽函数中调用关闭函数 将登录按钮使用qt5版本的连接到自定义的槽函数中&#xff0c;在槽函数中判断ui界面上输入的账号是否为"admin"&#xff0c;…

Linux搭建FISCO BCOS的第一个区块链网络

一、前言 FISCO BCOS是由金融区块链合作联盟&#xff08;深圳&#xff09;与微众银行共同发起的开源区块链项目&#xff0c;支持多链多账本&#xff0c;满足金融行业复杂业务需求。本文将介绍如何在Ubuntu操作系统上使用Linux命令搭建FISCO BCOS的第一个区块链网络。 目录 一…

K8S部署Java项目(Springboot项目)pod状态:CrashLoopBackOff

天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物。 每个人都有惰性&#xff0c;但不断学习是好好生活的根本&#xff0c;共勉&#xff01; 文章均为学习整理笔记&#xff0c;分享记录为主&#xff0c;如有错误请指正&#xff0c;共同学习进步。…

昇腾ACL应用开发之模型转换ATC

一.前提条件 在前面的章节中我们已经安装了包含模型转换的套件包CANN-TOOLKIT&#xff0c;默认的安装路径会在/usr/local/Ascend里面&#xff0c;我们将该套件所需要的东西加入到环境变量中以便我们调用&#xff1a; 将source /usr/local/Ascend/ascend-toolkit/set_env.sh加入…

人为物累,心为形役

一、人是什么 你是你&#xff0c;他是他&#xff0c;我是我&#xff0c;有什么区别吗&#xff0c;直到自我发现我与你不同时&#xff0c;不同是什么&#xff0c;身体结构&#xff1f;人生经历&#xff1f;所拥有的一切&#xff1f;暂时搁置这些的话&#xff0c;抽离我们的意识…

[ai笔记11] 论ai韭菜的自我修养

欢迎来到文思源想的ai空间&#xff0c;这是技术老兵学习ai以及观点分享的第11篇内容&#xff01; 上班之后时间确实少了许多&#xff0c;但是最近也没闲着&#xff0c;关于ai的学习一直在探索两个部分&#xff0c;一个是看那本有名的书《这就是ChatGPT》&#xff0c;另外一个则…

Gmail邮箱群发邮件的技巧?邮箱怎么绑定?

Gmail邮箱注册教程指南&#xff1f;如何注册新的Gmail邮箱帐户&#xff1f; Gmail邮箱作为谷歌推出的邮件服务&#xff0c;以其高效、稳定和便捷的特性受到广大用户的喜爱。然而&#xff0c;如何在Gmail中进行有效的群发邮件&#xff0c;接下来&#xff0c;蜂邮将给大家介绍一…

odoo16-API(Controller)带有验证访问的接口

odoo16-API&#xff08;Controller&#xff09;带有验证访问的接口 目前我使用odoo原生的登录token来验证登陆的有效性 废话不多说直接上代码 # 测试获取session_id import requests class GetOdooData(http.Controller):def getOdooToken(self):# http://localhost:8123访问…

【深入理解设计模式】 工厂设计模式

工厂设计模式 工厂设计模式是一种创建型设计模式&#xff0c;它提供了一种在不指定具体类的情况下创建对象的接口。在工厂设计模式中&#xff0c;我们定义一个创建对象的接口&#xff0c;让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。 工厂设计模式的目…

part2 思维导图(微分部分)

1. 导数和微分 2. 一元微分学 2.1 四则运算 2.2 口诀 2.3 导数计算 2.3.1 计算1 2.3.1 计算2

win32汇编定时器继续学习2

前面学习了win32汇编定时器&#xff0c;还非常不熟悉&#xff0c;继续熟悉&#xff0c;稍微增加一点功能&#xff1b; .386.model flat,stdcalloption casemap:noneinclude windows.inc include user32.inc includelib user32.lib include kernel32.inc includelib kernel32…

2024生物发酵展创新盛会-兰格恒流泵

​ 参展企业介绍 兰格恒流泵有限公司成立于1997年&#xff0c;是英国豪迈国际有限公司&#xff08;Halma&#xff09;的全资子公司。我们始终坚持以客户需求为导向&#xff0c;提供安全、高精度及高品质的流体传输设备和解决方案。兰格产品系列超…

前端架构: 脚手架之Chalk和Chalk-CLI使用教程

Chalk Chalk 是粉笔的意思, 它想表达的是&#xff0c;给我们的命令行中的文本添加颜色类似彩色粉笔的功能 在官方文档当中&#xff0c;它的 Highlights 核心特性 Expressive API Highly performant No dependencies Ability to nest styles 256/Truecolor color support Auto-…

提高工作效率,体验ONLYOFFICE办公软件

ONLYOFFICE办公软件 一、前言二、特点完整办公套件协作过程更容易 三、访问地址 一、前言 随着数字化办公的普及&#xff0c;办公软件在我们的工作中扮演着越来越重要的角色。为了提高工作效率&#xff0c;我们需要一个功能强大、易于使用的办公软件。ONLYOFFICE作为一款全功能…