Qt 异步实现事件的定时执行 - QTimer和QThread的联合使用

异步实现事件的定时执行 - QTimer和QThread的联合使用

  • 引言
  • 一、核心源码
  • 二、其信号和槽函数简述
  • 三、定时器及其moveToThread简述

引言

在 Qt 中,如果想要定时执行某些事件或函数,通常会使用 QTimer 类。QTimer 允许设置一个时间间隔,当这个时间间隔过去后,它会发出一个信号。可以将这个信号连接到一个槽函数,从而在该时间间隔到达时执行特定的操作。如果想要实现定时的操作是异步执行 (不阻塞主线程),可通过moveToThread将定时器移动到一个线程中,信号和槽的连接类型使用Qt::DirectConnection,保证槽函数执行是在定时器的线程中。效果如下图所示 (一秒执行一次):

在这里插入图片描述

一、核心源码

    1. 创建定时器以及线程,设定执行事件
    this->m_timer = new QTimer(nullptr);
    this->m_thread = new QThread(this);

    m_timer->setInterval(1000);
    m_timer->moveToThread(m_thread);
    connect(m_timer, &QTimer::timeout, this, [&](){
        QString time = QDateTime::currentDateTime().toString("hh:mm:ss.zzz");
        qDebug()<< time << " timer Thread ID:" << QThread::currentThreadId();
    }, Qt::DirectConnection);
    connect(m_thread, &QThread::started, m_timer, QOverload<>::of(&QTimer::start));
    connect(m_thread, &QThread::finished, m_timer, &QTimer::stop);
    m_thread->start();
    qDebug() << "Main Thread ID:" << QThread::currentThreadId();

首先创建定时器和线程,设定定时器间隔时间为1秒,并将定时器移动到线程中。方便起见直接使用兰姆达表达式设定定时器的定时槽函数. 使用信号和槽的形式调用定时器相关函数 (开始和停止)。最后启动线程即可.

    1. 内存释放
    m_thread->quit();
    m_thread->wait();
    m_thread->deleteLater();
    m_timer->deleteLater();

一般在父类或者父窗体的析构函数中执行,停止执行,释放内存。

二、其信号和槽函数简述

信号与槽相关知识可参考:
Qt 信号与槽的使用详解 - 多种绑定形式、同步异步、Lambda表达式等:https://blog.csdn.net/qq_38204686/article/details/139702275

    1. 使用信号和槽的形式调用定时器相关函数
      由于定时器已经被移动到线程中,所以不能直接在主线程中调用定时器相关函数。比如执行定时器停止m_timer->stop();会显示QObject::killTimer: Timers cannot be stopped from another thread

可参考
Qt: QTimer和QThread:https://www.cnblogs.com/lingdhox/p/4218051.html
https://stackoverflow.com/questions/53200294/qthread-with-qtimer-connection-issues

    1. 定时器开始槽函数需使用QOverload<>::of重载
      &QTimer::start有多个重载函数,比如void QTimer::start(int msec)void QTimer::start(),需使用QOverload<>::of指定调用哪一个重载函数 - (在<>中指明参数,比如<int>)。
      如果只这样写connect(m_thread, &QThread::started, m_timer, &QTimer::start);会报错,
      这样connect(m_thread, SIGNAL(started()), m_timer, SLOT(start()));是可行的,但不建议。

可参考
QThread with QTimer connection issues:https://stackoverflow.com/questions/53200294/qthread-with-qtimer-connection-issues
QT-信号槽有多个重载版本{ QOverload<_>::of(&::) }:https://blog.csdn.net/ugetoneshot/article/details/139169027

三、定时器及其moveToThread简述

    1. 创建定时器new QTimer(nullptr) 参数parent为空而不是this
      后续需要将定时器移动到另一线程,所以其父对象需为空

void QObject::moveToThread(QThread *targetThread)的官方解释:
更改此对象及其子对象的线程相关性。如果对象有父对象,则无法移动该对象,事件处理将在targetThread中继续。使用时需注意:此函数只能将对象从当前线程“推”到另一个线程,而不能将对象从任意线程“拉”到当前线程。

    1. 关于定时器的精度问题.
      如下方左图所示,近似每秒一触发,但是误差在2-3毫秒,设置setTimerType(Qt::PreciseTimer);之后误差只有1毫秒。

在这里插入图片描述 在这里插入图片描述

可参考
QT使用高精度定时器:https://blog.csdn.net/ljjjjjjjjjjj/article/details/130189550

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

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

相关文章

MySQL架构你了解多少?

MySQL是一个服务器-客户端应用&#xff0c;MySQL8.0服务器是由连接池、服务管理工具和公共组件、NoSQL接口、SQL接口、解析器、优化器、缓存、存储引擎、文件系统组成。MySQL还为各种编程语言提供了一套用于外部程序访问服务器的连接器。整体架构图如下所示: MySQLConnectors:为…

基于eBPF的procstat软件追踪等待锁和持有锁的时间

在并发编程中&#xff0c;锁的使用是保证线程安全的重要手段。然而&#xff0c;过度使用锁或者锁竞争可能导致性能瓶颈。为了分析程序中锁的使用情况&#xff0c;我们可以借助procstat软件来追踪程序加锁时间和等待锁的时间。procstat是一个基于eBPF&#xff08;extended Berke…

double和float的区别与使用

double和float类型的区别与使用 在Java中&#xff0c;double和float都是基本数据类型&#xff0c;用于表示浮点数&#xff08;即带有小数点的数&#xff09;。 它们在精度和范围上有所不同&#xff1a; double类型提供了更高的精度和更大的范围&#xff0c;而float类型则精度更…

读人工智能全传08人工智能的今天

1. 人工智能的今天 1.1. 未来&#xff0c;或许有些领域会有非常明显的人工智能痕迹&#xff0c;有些领域则不会 1.2. 2018年&#xff0c;来自计算机视觉处理器公司英伟达的研究人员证明了人工智能软件能够创造出虚假的人物照片&#xff0c;并且能够完全…

旷野之间2 - 如何训练医疗保健小型语言模型(AI-SLM)

​​​​ 在本文中,我们将研究如何针对疾病症状训练一个小型医疗保健语言模型。为此,我们将从HuggingFace获取数据集(用于训练我们的模型):https://huggingface.co/datasets/QuyenAnhDE/Diseases_Symptoms QuyenAnhDE/Diseases_Symptoms 数据集来自 Hugging Face。图片来源…

【初阶数据结构】1.算法复杂度

文章目录 1.数据结构前言1.1 数据结构1.2 算法1.3 如何学好数据结构和算法 2.算法效率2.1 复杂度的概念2.2 复杂度的重要性 3.时间复杂度3.1 大O的渐进表示法3.2 时间复杂度计算示例3.2.1 示例13.2.2 示例23.2.3 示例33.2.4 示例43.2.5 示例53.2.6 示例63.2.7 示例7 4.空间复杂…

C语言编程4:复合赋值,递增递减运算符,局部变量与全局变量,本地变量,转义字符

一篇文章带你玩转C语言基础语法4&#xff1a;复合赋值&#xff0c;递增递减运算符&#xff0c;局部变量与全局变量&#xff0c;本地变量&#xff0c;转义字符 一、复合赋值&#x1f33f; 1.1&#x1f4a0;定义 赋值就是给任意一个变量或者常量赋一个值&#xff0c;这个值可以…

《操作系统真象还原》学习笔记:第2章——编写MBR主引导记录

2.1 计算机的启动过程 载入内存&#xff1a; &#xff08;1&#xff09; 程序被加载器&#xff08;软件或硬件&#xff09;加载到内存某个区域 &#xff08;2&#xff09;CPU 的 cs:ip 寄存器被指向这个程序的起始地址 2.2 软件接力第一棒&#xff0c;BIOS 2.2.1 实模式下的…

多模态:Nougat详解

文章目录 前言一、模型结构1. encoder2. decoder3. set 二、数据增强三、数据splitting the pages 四、实验评估repetitions during inference 五、代码1. 环境安装2. Dataset&#xff08;dataset.py&#xff09;3. Model&#xff08;model.py&#xff09; 总结 前言 科学知识…

UML建模工具Draw.io简介

新书速览|《UML 2.5基础、建模与设计实践 Draw.io是一个非常出色的免费、开源、简洁、方便的绘图软件&#xff0c;利用这款软件可以绘制出生动有趣的图形&#xff0c;包括流程图、地图、网络架构图、UML用例图、流程图等。它支持各种快捷键&#xff0c;免费提供了1000多张画图…

【基于深度学习方法的激光雷达点云配准系列之GeoTransformer】——粗配准

【GeoTransformer系列】——粗配准 1.coarse_matching1.1 概要1.2 功能1.3 超参1.4 input1.5 output2 coarse_target2.1 概要2.2 功能2.3 input2.4 output在模型部分有了初步了解之后, 接下来我们对后续的粗配准、精配准等部分依次进行解读. 本篇主要来看粗配准部分, 代码是在G…

机器人三定律及伦理分析

全世界的机器人定律并没有一个统一的标准或体系&#xff0c;但是在科学文献中&#xff0c;最广为人知的是由科幻小说家阿西莫夫提出的“机器人三定律”。本文将以这些定律为基础&#xff0c;分析现有的机器人伦理和实际应用中的问题&#xff0c;给出若干实例&#xff0c;并对相…

贴脸细看Mixtral 8x7B- 稀疏混合专家模型(MoE)的创新与推动

贴脸细看Mixtral 8x7B- 稀疏混合专家模型&#xff08;MoE&#xff09;的创新与推动 原创 一路到底孟子敬 上堵吟 2024年01月15日 20:05 美国 I. 引言 A. Mixtral 8x7B的背景和目的 • 背景&#xff1a;随着大型语言模型在自然语言处理&#xff08;NLP&#xff09;领域的广泛…

类型“RouteRecordName”上不存在属性“includes”。 类型“symbol”上不存在属性“includes”

确定 route.name 运行时是 字符串&#xff0c;强制转换 为字符串。 removeRoute(id: string) { this.dynamRoute this.dynamRoute.filter(route > !(route.name as string).includes(id)) localStorage.setItem(dynamRoute, JSON.stringify(this.dynamRoute)) delete this.t…

Linux驱动开发-03字符设备驱动框架搭建

一、字符设备驱动开发步骤 驱动模块的加载和卸载&#xff08;将驱动编译模块&#xff0c;insmod加载驱动运行&#xff09;字符设备注册与注销&#xff08;我们的驱动实际上是去操作底层的硬件&#xff0c;所以需要向系统注册一个设备&#xff0c;告诉Linux系统&#xff0c;我有…

寂静孤独的404页面源码

寂静孤独的404页面源码&#xff0c;灯光闪烁动态效果&#xff0c;源码由HTMLCSSJS组成&#xff0c;记事本打开源码文件可以进行内容文字之类的修改&#xff0c;双击html文件可以本地运行效果&#xff0c;也可以上传到服务器里面&#xff0c;重定向这个界面 寂静孤独的404页面源…

普中51单片机:中断系统与寄存器解析(六)

文章目录 引言中断流程图中断优先级下降沿中断结构图中断相关寄存器IE中断允许寄存器&#xff08;可位寻址&#xff09;XICON辅助中断控制寄存器&#xff08;可位寻址&#xff09;TCON标志控制寄存器SCON串行口控制寄存器 中断号中断响应条件中断函数代码模板电路图开发板IO连接…

Spin Image(旋转图像)

Spin Image特征描述子原理 Spin Image是Johnson于1999年提出&#xff0c;Lazebnik于2005年完善的基于点云空间分布的特征描述方法&#xff0c;其思想是将一定区域的点云分布转换成二维的Spin Image&#xff0c;然后对场景和模型的Spin Image进行相似性度量。Spin Image方法与通…

OJhelper一款帮助你获取各大oj信息的软件

项目地址 应用功能 目前应用支持&#xff1a;查询、自定义、收藏各大oj比赛信息&#xff0c;跳转比赛界面。查询各大oj的Rating分以及题量&#xff0c;查看题量饼状图。 应用环境 windows和安卓端 应用预览&#xff1a; 维护概况 后期会提供持续更新&#xff0c;具体可以…

无法访问。你可能没有权限使用网络资源。请与这台服务器的管理员联系以查明你是否有访问权限。【解决办法】

问题描述 新建好一台windows虚拟机&#xff0c;两台设备网络是互通的&#xff0c;但是物理机在访问虚拟机的网络共享文件资源时&#xff0c;出现图下所示的报错&#xff1a;XXX无法访问。你可能没有权限使用网络资源。请与这台服务器的管理员联系以查明你是否有访问权限。用户…