QT 线程计时器
qt自带的计时器QTimer是与界面主线程绑定在一起的,如果操作界面有可能会影响计时器的执行,所以查找一些资料写了一个长期运行的线程计时器。
1.线程类的头文件
#ifndef WORKTH_H
#define WORKTH_H
#include <QDebug>
#include <QThread>
#include <QObject>
#include <atomic>
#include <mutex>
#include <condition_variable>
#include <chrono>
#include <thread>
class WorkTh : public QObject
{
Q_OBJECT
private:
#define SLEEP(a) std::this_thread::sleep_for(std::chrono::milliseconds(a));
void delay(int msec);
signals:
void workFinished(const qint64 cycleTime);
public:
WorkTh(QObject* parent = nullptr);
~WorkTh();
void doWork();
std::atomic<bool> m_isquit;
std::atomic<bool> m_ispuse;
std::mutex m_mutex;
std::condition_variable m_cond;
};
#endif
2.线程类,提供两种计算时差的方式,可根据需求自己选择
#include "WorkTh.h"
#include <QWaitCondition>
#include <qelapsedtimer.h>
WorkTh::WorkTh(QObject *parent)
: QObject(parent)
{
m_isquit = false;
m_ispuse = false;
p_zcobj = new ZcObj(parent);
}
void WorkTh::doWork()
{
qint64 argIntimestamp64;
qint64 finishtimestamp64;
qint64 currenttimestamp64;
qint64 intervaltimestamp64;
qint64 timestamp64;
qint64 lasttimestamp64=0;
qint64 nexttimestamp64 = 0;
QElapsedTimer timer;
timer.start();
while (!m_isquit)
{
//方式一,误差很小,cpu占用低 推荐
argIntimestamp64 = QDateTime::currentMSecsSinceEpoch();
std::unique_lock<std::mutex> locker(m_mutex);
while (m_ispuse) m_cond.wait(locker);
if (m_isquit)return;
//此处可写业务逻辑
emit workFinished(argIntimestamp64);
intervaltimestamp64 = argIntimestamp64 + 300- QDateTime::currentMSecsSinceEpoch();
//300ms执行一次
if (intervaltimestamp64 > 0)
{
delay(intervaltimestamp64);
}
//方式二,几乎没有误差,cup占用高
//while (timer.elapsed() >= SIB_MAIN_CYCLE)
//{
// timer.restart();
// timestamp64 = QDateTime::currentMSecsSinceEpoch();
// std::unique_lock<std::mutex> locker(m_mutex);
// while (m_ispuse) m_cond.wait(locker);
// if (m_isquit)return;
//
// //此处可写业务逻辑
// emit workFinished(timestamp64);
//}
}
}
void WorkTh::delay(int msec)
{
QEventLoop loop;
QTimer::singleShot(msec, &loop, SLOT(quit()));
loop.exec();
}
WorkTh::~WorkTh()
{
}
3.计时器使用
QThread p_thread = new QThread();
QThread p_work = new WorkTh();
p_work->moveToThread(p_thread);
//连接信号槽 如果参数是自定义的需要使用qRegisterMetaType进行声明
connect(p_thread, &QThread::started, p_work, &WorkTh::doWork);
connect(p_work, SIGNAL(workFinished(qint64)), this, SLOT(oneLogicMain(qint64)));
原文地址:https://blog.csdn.net/shu19880720/article/details/140120301
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!