news 2026/7/23 18:10:59

Qt 定时器放在线程中执行,支持随时开始和停止定时器。

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Qt 定时器放在线程中执行,支持随时开始和停止定时器。

前言:因为项目需要定时检查网络中设备是否能连通,需要定时去做ping操作,若是网络不通,则ping花费时间比较久(局域网大概4秒钟才能结束,当然如果设置超时时间啥的,也能很快返回,就是会报QProcess提前关闭的警告)。此外,我想要在设备连接后才去开始定时ping,要是断开后,则停止定时器,停止ping。网上有很多定时器使用线程的例子,但是没有讲到可以随时停止和开始的那种,本文结合实例,使用线程去执行定时器的定时操作。

一、定义定时器和线程变量。

在头文件中定义

#include <QTimer> #include <QThread> #include <QString> #include <QProcess> /** 监听网线拔出或者wifi断开情况的定时器 ***/ QTimer *detectNetCablePulloutTimer = NULL; /** 执行定时器的线程 **/ QThread *detectNetCablePulloutTimerThread = NULL; /** 开始检测网线拔出时或者wifi断开时的定时器 **/ void startDetectNetCablePulloutTimer(); /** 停止定时器 **/ void stopDetectNetCablePulloutTimer(); private slots: /** 检测网络连接情况的槽函数,在线程中执行 **/ void checkDeviceIsOnline();

二、开始定时器、停止定时器以及销毁定时器代码。

开始定时器代码:

void CurrentXXXClass::startDetectNetCablePulloutTimer() { // 先停止,确保开始之前是停止状态 stopDetectNetCablePulloutTimer(); if (detectNetCablePulloutTimer == NULL) { // 注意:构造函数是带this参数的,这个必须这么写,否则定时器槽函数无法在子线程中执行 detectNetCablePulloutTimerThread = new QThread(this); // 注意:构造函数是不带this参数的,这个必须这么写,否则定时器槽函数无法在子线程中执行 detectNetCablePulloutTimer = new QTimer(); // 5秒执行一次,局域网断开时,一般耗时4-5秒 detectNetCablePulloutTimer->setInterval(5000); // 定时操作放在线程中执行 detectNetCablePulloutTimer->moveToThread(detectNetCablePulloutTimerThread); // 定时任务放在线程中执行, 必须指定参数-Qt::DirectConnection connect(detectNetCablePulloutTimer, &QTimer::timeout, this, &CurrentXXXClass::checkDeviceIsOnline, Qt::DirectConnection); void (QTimer::*pStartFun)() = &QTimer::start; // 线程开始时,调用定时器的开始 connect(detectNetCablePulloutTimerThread, &QThread::started, detectNetCablePulloutTimer, pStartFun); // 线程结束时,调用定时器的结束,所以要停止定时器,只要调用线程的quit方法, // 同时防止提示:定时器停止和开始不在同一线程错误 connect(detectNetCablePulloutTimerThread, &QThread::finished, detectNetCablePulloutTimer, &QTimer::stop); } detectNetCablePulloutTimerThread->start(); }

停止定时器代码:

void CurrentXXXClass::stopDetectNetCablePulloutTimer() { if (detectNetCablePulloutTimerThread != NULL) { // 会调用定时器的stop方法 detectNetCablePulloutTimerThread->quit(); } }

销毁定时器,在析构函数中执行:

//销毁指针变量-注意先后顺序 if (detectNetCablePulloutTimerThread != NULL) { detectNetCablePulloutTimerThread->quit(); detectNetCablePulloutTimerThread->wait(); delete detectNetCablePulloutTimerThread; detectNetCablePulloutTimerThread = nullptr; } if (detectNetCablePulloutTimer != NULL) { // 定时器在线程中创建(父类不是当前类),让对象自己在所属线程销毁 detectNetCablePulloutTimer->deleteLater(); }

三、在槽函数中执行耗时操作。

此槽函数是在子线程中执行,若是执行完后要回到主线程执行某操作,则必须通过发送一个信号方式才能达到效果。

void CurrentXXXClass::checkDeviceIsOnline() { QString ip = "192.168.1.1"; // 若是timer使用了线程,则此函数在子线程中执行,执行比较耗时的操作 QProcess pingProcess; // 不设置-w参数 QString strArg = "ping " + ip + " -n 1 -i 2"; // qt 6 开始命令的方法 pingProcess.startCommand(strArg, QIODevice::ReadOnly); // 不带等待时间参数 pingProcess.waitForReadyRead(); // 不带等待时间参数 pingProcess.waitForFinished(); QString p_stdout = QString::fromLocal8Bit(pingProcess.readAllStandardOutput()); bool bPingSuccess = false; // 通过特殊字符串进行判断ping是否成功 if (p_stdout.contains("TTL=")) { // 网络连通 bPingSuccess = true; } else { // 网络不通 bPingSuccess = false; } }
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/23 18:09:25

AI模型优化与多模态学习实战指南

1. AI知识拓展的核心价值与应用场景在当今技术快速迭代的时代&#xff0c;AI知识拓展已经成为从业者保持竞争力的必修课。不同于基础入门教程&#xff0c;深度知识拓展更注重解决实际工作中的疑难杂症和前沿技术落地问题。我结合自己多年在AI项目实战中的经验&#xff0c;总结出…

作者头像 李华
网站建设 2026/7/23 18:02:10

关于在VM虚拟机下,安装OpenWrt软路由,所遇错误及解决方法。

首先是去阿里的openwrt源下载的镜像为img格式&#xff0c;vm虚拟无法识别&#xff0c;需要转换为iso格式或者vmdk格式&#xff0c;用软碟通转换iso格式失败&#xff0c;于是准备转换成vmdk格式&#xff0c;网上大部分采用starwindconverter软件&#xff0c;但是最新的版本老是报…

作者头像 李华
网站建设 2026/7/23 18:00:49

如何在PVE(Proxmox)中安装OpenWrt软路由?

出处: https://blog.itwk.cc/post/pve_install_openwrt.html 工具准备 WinSCP或者XFTP OpenWrt镜像(自行寻找) 安装好PVE的主机一台 安装教程 镜像上传 将下载好的OpenWrt img镜像上传到 PVE主机中(这里使用XFTP工具) 选择SFTP 点击确定,选择刚刚添加的主机。点击连接 输入用…

作者头像 李华
网站建设 2026/7/23 18:00:45

AI如何革新本科生论文写作:从选题到答辩的全流程优化

1. 本科生论文写作的痛点与破局思路写毕业论文大概是每个本科生最头疼的事情之一。去年指导学弟学妹论文时&#xff0c;我发现他们普遍存在几个典型问题&#xff1a;一是完全不知道从何下手&#xff0c;面对空白的文档一坐就是半天&#xff1b;二是文献查阅效率极低&#xff0c…

作者头像 李华
网站建设 2026/7/23 17:59:11

随身wifi刷openwrt变软路由--103s没网的解决

1. 刷入openwrt系统前,在备份文件里面找到下面四个文件,解压出来,将后缀改为.bin,放入openwrt系统包.2. 将备份文件image目录下文件夹解压出来,传入棒子,重启,即可.

作者头像 李华