【快速上手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.hqwc.cn/news/483466.html

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

相关文章

Py之pydantic:pydantic的简介、安装、使用方法之详细攻略

Py之pydantic&#xff1a;pydantic的简介、安装、使用方法之详细攻略 目录 pydantic的简介 1、Pydantic V1.10 vs. V2 pydantic的安装 pydantic的使用方法 1、简单的示例 pydantic的简介 pydantic是使用Python类型提示进行数据验证。快速且可扩展&#xff0c;Pydantic与您…

车灯裂了用什么胶修复?

当车灯出现裂缝、破口、缺损、裂痕、破裂、破损、崩角、掉角等问题时&#xff0c;可以使用车灯无痕修复专用UV胶进行修复。车灯无痕修复专用UV胶是一种经过处理的UV树脂胶&#xff0c;主要成份是改性丙烯酸UV树脂。应用在车灯的专业无痕修复领域。 具有如下特点&#xff1a; 1…

C++入门学习(三十二)二维数组定义方式

一维数组类似于一条“线”&#xff0c;而二维数组类似于一个“面”&#xff0c;二维数组也更像一个表格&#xff0c;由我们在“表格”中查询数据。 1、先定义数组&#xff0c;后赋值 int arr[2][3]; #include <iostream> using namespace std;int main() { int arr…

【鸿蒙系统学习笔记】网络请求

一、介绍 资料来自官网&#xff1a;文档中心 网络管理模块主要提供以下功能&#xff1a; HTTP数据请求&#xff1a;通过HTTP发起一个数据请求。WebSocket连接&#xff1a;使用WebSocket建立服务器与客户端的双向连接。Socket连接&#xff1a;通过Socket进行数据传输。 日常…

(十二)【Jmeter】线程(Threads(Users))之tearDown 线程组

简述 操作路径如下: 作用:在正式测试结束后执行清理操作,如关闭连接、释放资源等。配置:设置清理操作的采样器、执行顺序等参数。使用场景:确保在测试结束后应用程序恢复到正常状态,避免资源泄漏或对其他测试的影响。优点:提供清理操作,确保测试环境的整洁和可重复性…

306_C++_QT_创建多个tag页面,使用QMdiArea容器控件,每个页面都是一个新的表格[或者其他]页面

程序目的是可以打开多个styles文件(int后缀文件),且是tag样式的(就是可以切多个页面出来,并且能够单独关闭);其中读取ini文件,将其插入到表格中的操作,也是比较复杂的,因为需要保持RGB字符串和前面的说明字符串对齐 ini文件举例: [MainMenu] Foreground\Selected=&…

在电脑上使用网络摄像头录制视频的 4 大方法

在线采访、会议、演示和一对一互动都通过网络摄像头进行。无论是制作教学视频还是回顾在线会议的重要细节&#xff0c;人们经常需要使用网络摄像头录制视频。 可以使用不同的方法和工具来处理此任务。在以下部分中&#xff0c;您将找到使用网络摄像头或从网络摄像头录制视频的…

stm32——hal库学习笔记(DAC)

这里写目录标题 一、DAC简介&#xff08;了解&#xff09;1.1&#xff0c;什么是DAC&#xff1f;1.2&#xff0c;DAC的特性参数1.3&#xff0c;STM32各系列DAC的主要特性 二、DAC工作原理&#xff08;掌握&#xff09;2.1&#xff0c;DAC框图简介&#xff08;F1&#xff09;2.2…

万界星空科技电子机电行业MES系统,2000元/年起

电子行业在生产管理上具有典型的离散制造特点&#xff0c;采用多品种、多批量或单件的生产组织方式。产品升级换代迅速&#xff0c;生命周期短&#xff0c;变更频繁&#xff0c;版本控制复杂。 同时产品的种类较多&#xff0c;非标准产品多&#xff0c;加工工序复杂&#xff0…

git中将所有修改的文件上传到暂存区

案例&#xff1a; 我将本地的多个文件进行了修改&#xff0c;导致文件发生了变化。使用git status命令&#xff0c;查看文件的状态&#xff0c;发现有多个文件是modified&#xff0c;即被修改了。 本地文件发生了变化&#xff0c;需要将modified的文件添加到暂存区&#xff0c…

【2.3深度学习开发任务实例】(1)神经网络模型的特点【大厂AI课学习笔记】

从本章开始&#xff0c;我把标题的顺序变了一下&#xff0c;大厂AI课笔记&#xff0c;放到后面。因为我发现App上&#xff0c;标题无法显示完全。 从本章开始&#xff0c;要学习深度学习开发任务的全部过程了。 我们将通过小汽车识别赛道上的标志牌&#xff0c;给出检测框&am…

从源码解析Kruise(K8S)原地升级原理

从源码解析Kruise原地升级原理 本文从源码的角度分析 Kruise 原地升级相关功能的实现。 本篇Kruise版本为v1.5.2。 Kruise项目地址: https://github.com/openkruise/kruise 更多云原生、K8S相关文章请点击【专栏】查看&#xff01; 原地升级的概念 当我们使用deployment等Wor…