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

news2024/9/21 4:39:42

异步实现事件的定时执行 - 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

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

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

相关文章

聚星文社一键生成工具绘唐3科技AI工具

聚星文社一键生成工具绘唐3科技AI工具 绘唐3.0——用户文档 - 飞书云文档 聚星文社一键生成工具绘唐3科技AI工具是一个基于人工智能技术的辅助创作工具&#xff0c;可以帮助用户快速生成有关唐朝科技的文本内容。该工具利用自然语言处理和机器学习等技术&#xff0c;通过输入一…

opencv读取视频文件夹内视频的名字_时长_帧率_分辨率写入excel-cnblog

看视频的时候有的视频文件名贼长。想要翻看&#xff0c;在文件夹里根本显示不出来&#xff0c;缩短又会丢失一些信息&#xff0c;所以我写了一份Python代码&#xff0c;直接获取视频的名字&#xff0c;时长&#xff0c;帧率&#xff0c;还有分辨率写到excel里。 实际效果如下图…

Cesium自定义着色器构件三角面片【闪烁】问题,但是一移动视角就闪烁

问题&#xff1a;已知各个顶点的坐标信息、颜色和索引信息&#xff0c;并自定义绘制三角面片。 但是绘制的三角面片随着视角稍微改动就会出现闪烁现象&#xff01;&#xff01;&#xff01;why? Cesium数据类型的精度问题&#xff0c;例如下面为了获取能接收到高精度坐标信息…

linux磁盘分区管理

首先关机状态下&#xff0c;先配置硬盘 硬盘分区管理 识别硬盘 》分区规划 》 格式化 》 挂载使用 [rootlocalhost ~]# lsblk 查看硬盘 分区划分&#xff08;m帮助, p 查看分区, n 创建分区, d 删除分区, q 退出, w 保存&#xff0c; g gpt分区&#xff09; [roo…

华为云发起,openGemini正式成为CNCF官方项目!

openGemini 正式成为 CNCF 官方项目 北京时间2024年7月9日&#xff0c;云原生计算基金会&#xff08;CNCF&#xff09;正式接纳云原生高性能时序数据库项目 openGemini。openGemini的加入&#xff0c;极大地丰富了云原生数据库技术的探索、创新和发展。 openGemini是华为云数据…

打开excel时弹出stdole32.tlb

问题描述 打开excel时弹出stdole32.tlb 如下图&#xff1a; 解决方法 打开 Microsoft Excel 并收到关于 stdole32.tlb 的错误提示时&#xff0c;通常意味着与 Excel 相关的某个组件或类型库可能已损坏或不兼容。 stdole32.tlb 是一个用于存储自动化对象定义的类型库&#x…

BN的 作用

1、背景&#xff1a; 卷积神经网络的出现&#xff0c;网络参数量大大减低&#xff0c;使得几十层的深层网络成为可能。然而&#xff0c;在残差网络出现之前&#xff0c;网络的加深使得网络训练变得非常不稳定&#xff0c;甚至出现网络长时间不更新或者不收敛的情形&#xff0c;…

利用 Selenium 和 Python 实现网页新闻链接抓取

在网络数据分析和信息检索中&#xff0c;爬虫是一项非常重要的技术。爬虫可以自动化地从网页中提取信息&#xff0c;极大地提升数据收集的效率。本文将以一个具体的代码实例&#xff0c;讲解如何使用 Selenium 库进行网页新闻链接的抓取。 前期准备 在开始之前&#xff0c;需…

3-7 使用深度学习解决温度即示数问题

3-7 使用深度学习解决温度即示数问题 直接上代码 %matplotlib inline import matplotlib.pyplot as plt import numpy as np import torch torch.set_printoptions(edgeitems2, linewidth75)设置Jupyter Notebook在单元格中内嵌显示图像&#xff0c;导入所需库并设置PyTorch的…

实时温湿度监测系统:Micropython编码ESP32与DHT22模块的无线数据传输与PC端接收项目

实时温湿度监测系统 前言项目目的项目材料项目步骤模拟ESP32接线连接测试搭建PC端ESP32拷录环境对ESP32进行拷录PC端搭建桌面组件本地数据接收桌面小组件部分 实验总结 前言 人生苦短&#xff0c;我用Python。 由于我在日常工作中经常使用Python&#xff0c;因此在进行该项目…

物流工业三防平板实时跟踪货物位置和状态

在当今全球化和高度数字化的商业环境中&#xff0c;物流行业的高效运作对于企业的成功和经济的繁荣至关重要。货物的准确、实时跟踪不仅能提高物流效率&#xff0c;还能增强客户满意度&#xff0c;降低运营成本。物流工业三防平板的出现&#xff0c;为实现货物位置和状态的实时…

使用redis进行短信登录验证(验证码打印在控制台)

使用redis进行短信登录验证 一、流程1. 总体流程图2. 流程文字讲解&#xff1a;3.代码3.1 UserServiceImpl&#xff1a;&#xff08;难点&#xff09;3.2 拦截器LoginInterceptor&#xff1a;3.3 拦截器配置类&#xff1a; 4 功能实现&#xff0c;成功存入redis &#xff08;黑…

2017年,我成为了技术博主

2017年9月&#xff0c;我已经大三了。 >>上一篇&#xff08;爪哇&#xff0c;我初窥门径&#xff09; 我大二学了很多java技术&#xff0c;看似我一会就把javaweb/ssh/ssm这些技术栈给学了。 这些技术确实不难&#xff0c;即便是我&#xff0c;我都能学会&#xff0c;…

深入理解 LXC (Linux Containers)

目录 引言LXC 的定义LXC 的架构LXC 的工作原理LXC 的应用场景LXC 在 CentOS 上的常见命令实验场景模拟总结 1. 引言 在现代 IT 基础设施中&#xff0c;容器技术已经成为一种重要的应用和部署方式。与虚拟机相比&#xff0c;容器具有更高的效率、更轻量的特性和更快的启动速度…

MySQL GROUP_CONCAT 函数详解与实战应用

提示&#xff1a;在需要将多个值组合成一个列表时&#xff0c;GROUP_CONCAT() 函数为 MySQL 提供了一种强大的方式来处理数据 文章目录 前言什么是 GROUP_CONCAT()基本语法 示例使用 GROUP_CONCAT()去除重复值排序结果 前言 提示&#xff1a;这里可以添加本文要记录的大概内容…

第一次作业--数据库-搭建MySQL环境

一、下载 二、进入安装向导 1.选择Custom &#xff0c;然后点击next 2.选择安装地址 点击第一个MySQL Servers然后依次点击打开到MySQL Server 8.0.37-X64 点击向右的绿色箭头 点击MySQL Server 8.0.37-X64 然后看到下面的蓝色Advanced Options 更改安装路径 然后点击next …

刷题(day02)

1、leetcode136.删除链表的结点 给定单向链表的头指针和一个要删除的节点的值&#xff0c;定义一个函数删除该节点。 返回删除后的链表的头节点。 示例 1: 输入: head [4,5,1,9], val 5 输出: [4,1,9] 解释: 给定你链表中值为 5 的第二个节点&#xff0c;那么在调用了你的函数…

说说iOS苹果的“开发者模式”什么时候需要打开 需不需要提前打开

在 iOS 开发过程中&#xff0c;开发者模式&#xff08;Developer Mode&#xff09;是一个非常重要的功能&#xff0c;它允许开发者在设备上运行和调试自己的应用程序。 经常有人私信或在群里问到&#xff0c;“我没有开发者模式&#xff0c;怎么办”&#xff0c;“开发者模式是…

优秀策划人必逛的地方,你不会还不知道吧?

道叔今天依然记得当初刚入行的时候&#xff0c;每天为完成策划任务&#xff0c;焦虑的整晚睡不着觉的痛苦。 但其实……很多时候&#xff0c;选择比努力更重要 优秀的策划和文案&#xff0c;也从来不是天生&#xff0c;你要走的路&#xff0c;前人都已经走过,你要做的仅仅是整…

windows JDK11 与JDK1.8自动切换,以及切换后失效的问题

1.windows安装不同环境的jdk 2.切换jdk 3.切换失败 原因&#xff1a;这是因为当我们安装并配置好JDK11之后它会自动生成一个环境变量&#xff08;此变量我们看不到&#xff09;&#xff0c;此环境变量优先级较高&#xff0c;导致我们在切换回JDK8后系统会先读取到JDK11生成的…