QObject_timer

QObject

int QObject::startTimer(int interval, Qt::TimerType timerType = Qt::CoarseTimer)

QObject本身自带的定时器函数,简单的定时任务不需要再使用QTimer,只需要重写timerEvent即可。
interval单位是毫秒,且必须大于等于0
如果interval为0,则每当没有更多的窗口系统事件需要处理时,计时器事件发生一次。

Qt::TimerType:枚举类型有3个值
Qt::PreciseTimer :精确计时器试图保持毫秒级的精度
Qt::CoarseTimer :粗定时器试图将准确度保持在所需间隔的5%以内(默认值)
Qt::VeryCoarseTimer :非常粗糙的计时器只保持完整的秒精度

返回定时器标识符,如果无法启动定时器则返回零。

  1. 调用startTimer后每间隔interval毫秒,触发一次timerEvent事件,直到killTimer()被调用或者对象析构。
  2. 多次调用startTimer,会添加多个定时器,根据返回的id判断是触发的那个定时器超时事件
  3. 间隔的计算:在触发timerEvent前已经设置好了下次触发的超时时间
  4. 每次事件循环都会检查所有的定时器,循环触发所有已经超时的定时器事件(触发前已经设置好下次的超时时间)
  5. movethread会导致定时器重新开始计时,频繁的movethread可能会导致无法触发timerEvent
int QObject::startTimer(int interval, Qt::TimerType timerType)
{Q_D(QObject);if (Q_UNLIKELY(interval < 0)) {qWarning("QObject::startTimer: Timers cannot have negative intervals");return 0;}auto thisThreadData = d->threadData.loadRelaxed();if (Q_UNLIKELY(!thisThreadData->hasEventDispatcher())) {qWarning("QObject::startTimer: Timers can only be used with threads started with QThread");return 0;}//必须在同一线程调用才有效if (Q_UNLIKELY(thread() != QThread::currentThread())) {qWarning("QObject::startTimer: Timers cannot be started from another thread");return 0;}//向事件分发器注册定时器int timerId = thisThreadData->eventDispatcher.loadRelaxed()->registerTimer(interval, timerType, this);if (!d->extraData)d->extraData = new QObjectPrivate::ExtraData;d->extraData->runningTimers.append(timerId);//append意味着可以添加多个定时器return timerId;
}registerTimer-》timerInsert(将timer加入列表当中,并按照触发先后顺序排列)void QTimerInfoList::registerTimer(int timerId, int interval, Qt::TimerType timerType, QObject *object)
{QTimerInfo *t = new QTimerInfo;t->id = timerId;t->interval = interval;t->timerType = timerType;t->obj = object;t->activateRef = nullptr;timespec expected = updateCurrentTime() + interval;t->timeout = expected;//超时时间timerInsert(t);
}
每次事件循环processEvents时,调用activateTimers处理
int QTimerInfoList::activateTimers()
{int n_act = 0, maxCount = 0;firstTimerInfo = nullptr;timespec currentTime = updateCurrentTime();//先找到所有到期的定时器,后面依次调用sendEvent触发timerEvent处理事件for (QTimerInfoList::const_iterator it = constBegin(); it != constEnd(); ++it) {if (currentTime < (*it)->timeout)break;maxCount++;}while (maxCount--) {if (isEmpty())break;QTimerInfo *currentTimerInfo = constFirst();if (currentTime < currentTimerInfo->timeout)break; // no timer has expiredremoveFirst();//从这里可以看出,下次触发时间是在调用timerevent前就已经计算好了的,//如果timerevent执行时间较长大于时间间隔interval,下次事件循环判断其超时会直接触发calculateNextTimeout(currentTimerInfo, currentTime);//计算下次触发时间timerInsert(currentTimerInfo);//下次的超时信息并加入到超时列表里面,按照超时先后顺序排列的if (!currentTimerInfo->activateRef) {QTimerEvent e(currentTimerInfo->id);QCoreApplication::sendEvent(currentTimerInfo->obj, &e);//最终调用到timerevent,同步触发}}return n_act;
}void QTimerInfoList::timerInsert(QTimerInfo *ti)
{int index = size();while (index--) {const QTimerInfo * const t = at(index);if (!(ti->timeout < t->timeout))//按触发先后顺序排列,timeout小的排在前面break;}insert(index+1, ti);
}

void QObject::killTimer(int id)

id为startTimer的返回值
killTimer被调用时将结束对应的定时器,其不再触发timerEvent事件。
注意:不能在另一个线程里面结束它,即在另一个线程调用此函数无效,定时器不会被结束

void QObject::killTimer(int id)
{Q_D(QObject);//不能在另一个线程里面结束它if (Q_UNLIKELY(thread() != QThread::currentThread())) {qWarning("QObject::killTimer: Timers cannot be stopped from another thread");return;}if (id) {auto thisThreadData = d->threadData.loadRelaxed();if (thisThreadData->hasEventDispatcher())thisThreadData->eventDispatcher.loadRelaxed()->unregisterTimer(id);d->extraData->runningTimers.remove(at);QAbstractEventDispatcherPrivate::releaseTimerId(id);}
}bool QTimerInfoList::unregisterTimer(int timerId)
{// set timer inactivefor (int i = 0; i < count(); ++i) {QTimerInfo *t = at(i);if (t->id == timerId) {//移除removeAt(i);if (t == firstTimerInfo)firstTimerInfo = nullptr;if (t->activateRef)*(t->activateRef) = nullptr;delete t;return true;}}// id not foundreturn false;
}

void QObject::timerEvent(QTimerEvent *)

QObject默认空实现


void QObject::timerEvent(QTimerEvent *)
{
}

一般都是继承后重写实现自己的功能

myobject.h#include<QObject>
class myobject : public QObject
{Q_OBJECT
public:myobject(QObject *parent = nullptr):QObject(parent){}
protected:
virtual void timerEvent(QTimerEvent *event);
};myobject.cpp#include<QTimerEvent>
virtual void timerEvent(QTimerEvent *event)
{qDebug()<<"timerId="<<event->timerId();
}main.cppint main(int argc, char *argv[])
{QApplication a(argc, argv);myobject *obj1= new  myobject(nullptr);obj1->startTimer(1000);obj1->startTimer(5000);obj1->startTimer(10000);return a.exec();
}

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

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

相关文章

C#编程-实现在文本文件中的读和写

实现在文本文件中的读和写 Stream类用于从文本文件读取数据和向文本文件写入数据。它是一个抽象类,支持向流读写字节。如果文件的数据仅是文本,那么您可以使用StreamReader类和StreamWriter类来完成相应的读和写任务。 StreamReader类 StreamReader类继承自从抽象类TextRea…

机器学习指南:如何学习机器学习?

机器学习 一、介绍 你有没有想过计算机是如何从数据中学习和变得更聪明的&#xff1f;这就是机器学习 &#xff08;ML&#xff09; 的魔力&#xff01;这就像计算机科学和统计学的酷炫组合&#xff0c;计算机从大量信息中学习以解决问题并做出预测&#xff0c;就像人类一样。 …

面试题:什么是雪花算法?啥原理?

SnowFlake 算法&#xff0c;是 Twitter 开源的分布式 ID 生成算法。 其核心思想就是&#xff1a;使用一个 64 bit 的 long 型的数字作为全局唯一 ID。在分布式系统中的应用十分广泛&#xff0c;且 ID 引入了时间戳&#xff0c;基本上保持自增的&#xff0c;后面的代码中有详细…

UV胶水能够粘接聚苯乙烯PS吗?需要注意哪些事项?又有哪些优势呢?

聚苯乙烯&#xff08;Polystyrene&#xff0c;简称PS&#xff09;是一种常见的合成聚合物&#xff0c;属于热塑性塑料。它是由苯乙烯单体聚合而成的&#xff0c;具有轻质、透明或半透明、电绝缘性好等特点。常见: 包装材料白色泡沫塑料&#xff08;EPS&#xff0c;用于包装、保…

不断发展的识别技术为多个行业带来新机遇

随着人工智能和机器学习技术的不断进步&#xff0c;识别技术已经得到了广泛的应用。识别技术是指通过计算机软件和硬件的配合&#xff0c;自动识别输入的信息并转换为可处理的数据的过程。这种技术的应用范围非常广泛&#xff0c;包括人脸识别、语音识别、文字识别、车牌识别等…

java注解学习

java注解 Annotation 为什么要学注解&#xff1f; 在日常开发中&#xff0c;基本都是在使用别人定义或是各种框架的注解&#xff0c;比如Spring框架中常用的一些注解&#xff1a;Controller、Service、RequestMapping&#xff0c;以此来实现某些功能&#xff0c;但是却不知道如…

神经网络(Neural Networks)

什么是机器学习 神经网络&#xff08;Neural Networks&#xff09;&#xff0c;也称为人工神经网络&#xff08;Artificial Neural Networks&#xff0c;ANNs&#xff09;是一种受到生物神经网络启发而设计的机器学习模型。神经网络由神经元&#xff08;或节点&#xff09;组成…

HarmonyOS@Link装饰器:父子双向同步

Link装饰器&#xff1a;父子双向同步 子组件中被Link装饰的变量与其父组件中对应的数据源建立双向数据绑定。 说明 从API version 9开始&#xff0c;该装饰器支持在ArkTS卡片中使用。 概述 Link装饰的变量与其父组件中的数据源共享相同的值。 装饰器使用规则说明 Link变…

echarts使用之柱状图

一、引入Echarts npm install eacharts --save 二、选择一个Echarts图 选择创建一个柱状图 option { // x轴参数的基本配置xAxis: {type: category,data: [Mon, Tue, Wed, Thu, Fri, Sat, Sun] //X轴数据}, // y轴参数的基本配置yAxis: {type: value}, // series:[{data: …

富文本BraftEditor引起的bug

1、BraftEditor踩坑1 #基于之前写的一篇BraftEditor的使用# 1. 问题起源&#xff1a; 打开编辑弹窗--> 下面页面所示--> 当进行分类选择时候&#xff0c;就会报错&#xff0c;并且这个报错还不是一直都有&#xff0c;6次选择出现一次报错吧 2. 解决&#xff1a; 2.1 起…

CES 2024:LG专注于新产品的人工智能变革

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

蓝牙模块在电动汽车充电设施中的创新应用

随着电动汽车的普及&#xff0c;充电设施的便捷性和智能化成为关键的发展方向。蓝牙技术作为一种无线通信技术&#xff0c;在电动汽车充电设施中发挥着越来越重要的作用。本文将深入探讨蓝牙模块在电动汽车充电设施中的创新应用&#xff0c;以提高充电体验、提升管理效率&#…

vue3.2引用unplugin-auto-import插入,解放开发中import组件

目录 前言引用unplugin-auto-import插件的优缺点优点缺点 unplugin-auto-import插件引入安装插件配置vite配置更新TypeScript配置使用代码位置 总结 前言 是否添加unplugin-auto-import取决于项目需求和团队习惯。如果项目中频繁使用Vue相关API&#xff0c;并且团队成员都熟悉这…

MulticoreWare与Imagination一同按下汽车计算工作负载的“加速键”

中国北京 – 2024年1月8日 - MulticoreWare Inc与Imagination Technologies共同宣布已在德州仪器TDA4VM处理器上实现了GPU计算&#xff0c;不仅使算力提升了约50 GFLOPS&#xff0c;而且还实现了自动驾驶和高级驾驶辅助系统&#xff08;ADAS&#xff09;常见工作负载性能的跃升…

使用Docker部署PDF多功能工具Stirling-PDF

1.服务器上安装docker 安装比较简单&#xff0c;这种安装的Docker不是最新版本&#xff0c;不过对于学习够用了&#xff0c;依次执行下面命令进行安装。 sudo apt install docker.io sudo systemctl start docker sudo systemctl enable docker 查看是否安装成功 $ docker …

前端项目由nginx迁移到apache httpd

前端项目由nginx迁移到apache httpd 前端项目存放目录为 /var/www/dist 虚拟主机端口80 反向代理拦截 /prod-api 后端服务地址 http://192.168.0.44:8097 <VirtualHost *:80>DocumentRoot /var/www/distServerName www.dist.com<Directory /var/www/dist>RewriteEn…

PCL 使用克拉默法则进行四点定球(C++详细过程版)

目录 一、算法原理二、代码实现三、计算结果本文由CSDN点云侠原创,PCL 使用克拉默法则进行四点定球(C++详细过程版),爬虫自重。如果你不是在点云侠的博客中看到该文章,那么此处便是不要脸的爬虫与GPT生成的文章。 一、算法原理 已知空间内不共面的四个点,设其坐标为 A (…

鼠标随动指定区域高亮显示(Excel聚光灯)

实例需求&#xff1a;工作表中数据表实现跟随鼠标选中高亮效果&#xff0c;需要注意如下几个细节需求 数据表为连续区域&#xff0c;但是不一定从A1单元格开始数据表的前两行&#xff08;标题行&#xff09;不使用高亮效果数据表中已经应用了条件格式&#xff0c;高亮显示取消…

计算机网络专栏目录

1. http header 请求头 x-forwarded-for 2. HTTP/HTTPS、TLS/SSL 协议

redis持久化与SpringBoot整合

redis持久化与SpringBoot整合 1、Redis全局命令1.2、Redis事务 2、Redis持久化2.1、RDB方式2.1.1、客户端触发机制2.1.2、服务端触发机制2.2.3、配置生成快照名称和位置2.2.4、优点2.2.5、缺点 2.2、AOF方式2.2.1、优点2.2.2、缺点 2.3、RDB-AOF混合方式2.4、持久化机制的选择 …