提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
前言
在制作qt软件时,我们经常会用到qtimer定时器以及将其在非主线程中进行使用,甚至有的时候还需要和主线程进行交互。我总结了两种用法,仅供参考
一、moveToThread
1.主线程头文件,主线程窗口类里面新建以下变量
代码如下:一个时间间隔,两个变量。记得初始化指针为空
const int m_timer_interval__ = 5000;
QTimer* monitor_timer__ = nullptr;
QThread* monitor_thread__ = nullptr;
2.主线程生成定时器并迁移到线程中
代码如下:qtimer不要有parent,线程可以有。先开线程,再开定时器,开启定时器以后,再迁移到线程中即可。
monitor_thread__ = new QThread(this);
monitor_thread__->start();
monitor_timer__ = new QTimer();
connect(monitor_timer__, SIGNAL(timeout()), this, SLOT(GetResource()), Qt::DirectConnection);
monitor_timer__->start(m_timer_interval__);
monitor_timer__->moveToThread(monitor_thread__);
connect(monitor_thread__, SIGNAL(started()), monitor_timer__, SLOT(start()));
connect(monitor_thread__, SIGNAL(finished()), monitor_timer__, SLOT(stop()));
GetRsource()可以换成任何你想定时执行的任务(主线程的函数即可),如果要交互,可以用信号和槽理论上时可以和主线程之间通信的。
二、继承QThread,在thread里造个计时器,然后信号通信
1.继承线程的写法
代码如下,h:
#pragma once
#include <qthread.h>
#include <atomic>
#include <QMutex>
#include <QWaitCondition>
class timerThread :
public QThread
{
Q_OBJECT
public:
timerThread(QObject* parent = nullptr);
~timerThread() override;
enum State
{
Stoped, ///<停止状态,包括从未启动过和启动后被停止
Running, ///<运行状态
Paused ///<暂停状态
};
State state() const;
private:
std::atomic_bool pauseFlag;
std::atomic_bool stopFlag;
QMutex mutex;
QWaitCondition condition;
QTimer* _timer = nullptr;
public slots:
void timerRun();//用于反复跑的内容
void start(Priority pri = InheritPriority);
void stop_th();
void pause();
void resume();
protected:
virtual void run() override final;
signals:
void sendCtrlSignal();//和主线程交互触发的signal
};
代码如下,cpp:
#include "timerThread.h"
#include <QDebug>
timerThread::timerThread(QObject* parent)
: QThread(parent),
pauseFlag(false),
stopFlag(false)
{
}
timerThread::~timerThread()
{
stop_th();
}
timerThread::State timerThread::state() const
{
State s = Stoped;
if (!timerThread::isRunning())
{
s = Stoped;
}
else if (timerThread::isRunning() && pauseFlag)
{
s = Paused;
}
else if (timerThread::isRunning() && (!pauseFlag))
{
s = Running;
}
return s;
}
void timerThread::start(Priority pri)
{
QThread::start(pri);
}
void timerThread::stop_th()
{
if (timerThread::isRunning())
{
stopFlag = true;
condition.wakeAll();
timerThread::quit();
timerThread::wait();
}
}
void timerThread::pause()
{
if (timerThread::isRunning())
{
pauseFlag = true;
}
}
void timerThread::resume()
{
if (timerThread::isRunning())
{
pauseFlag = false;
condition.wakeAll();
}
}
void timerThread::run()
{
qDebug() << QString("开始执行计时线程") << timerThread::currentThreadId();
_timer = new QTimer();
_timer->setInterval(MODBUS_WAIT * 20);
connect(_timer, &QTimer::timeout, [=] {
if (!pauseFlag)
{
timerRun();
}
if (stopFlag)
{
_timer->stop();
}
});
_timer->start();
this->exec();
pauseFlag = false;
stopFlag = false;
qDebug() << QString("结束执行计时线程") << timerThread::currentThreadId();
}
void timerThread::timerRun()
{
emit sendCtrlSignal();
}
2.主线程调用
1.挂上头文件#include “timerThread.h”
2.主线程对应的头文件里,最上边,类外加上class timerThread;提前声明一下
3.cpp文件里,生成一个,然后控制一下就行了,剩下的就不用我教了。最后记得主线程结束的时候,最好手动判定一下是否运行,然后释放一下。
总结
以上即为QTimer和QThread联合使用的学习记录。