QT----基于QML的计时器
赶上了实习的末班车,现在在做QML开发,第一天的学习成果,一个计时器.逻辑挺简单的,纯QML实现,代码在仓库QT-Timer
多线程优化
在使用的过程中发现自己的计时器时间会慢,并且一直点击记录的话时间1s可以走10s,排查发现是在计时器的间隔取得太小了,取了1太过于消耗资源,改成10的话能解决这个问题.同时也想尝试使用线程来解决.
新建TimerThread 类继承自QObject,只有这样才能使用线程.我们需要发送时间和运行的状态,因此使用信号和QML文件通信
#ifndef TIMERTHREAD_H
#define TIMERTHREAD_H
#include <QObject>
#include <QTimer>
#include <QThread>
#include <cmath>
/******************************************************************************
*
* @file timerthread.h
* @brief 把计时放入线程
*
* @author 纯真丁一郎
* @date 2024/09/18
* @Blog https://www.relxdingyilang.cn/
* @history
*****************************************************************************/
class TimerThread : public QObject
{
Q_OBJECT
public:
explicit TimerThread(QObject *parent = nullptr);
//判断运行状态
bool isRunning = false;
QString caculateTime(int totaltime);
signals:
void timeUpdated(QString totaltimestr); //发送时间给主界面
void sig_isRunning(bool isRunning);//发送状态
public slots:
void start();
void stop();
void pause();
void onTimeout();
private:
int m_totaltime; //总时间
QTimer *timer;
};
#endif // TIMERTHREAD_H
cpp里实现计时的功能启动计时器,计算时间格式.使用定时器的timeout信号,让我们的时间增加
#include "timerthread.h"
TimerThread::TimerThread(QObject *parent)
: QObject{parent}
{
m_totaltime = 0;
timer = new QTimer(this);
connect(timer,&QTimer::timeout,this,&TimerThread::onTimeout);
}
void TimerThread::start(){
timer->start(1);
isRunning = true;
emit sig_isRunning(isRunning);
}
void TimerThread::pause(){
timer->stop();
isRunning = false;
emit sig_isRunning(isRunning);
}
void TimerThread::stop(){
timer->stop();
isRunning = false;
m_totaltime = 0;
emit sig_isRunning(isRunning);
}
void TimerThread::onTimeout(){
//计时
m_totaltime += 1;
emit timeUpdated(caculateTime(m_totaltime));
}
QString TimerThread::caculateTime(int totaltime){
//格式化字符串
int millisecond =totaltime % 1000;
millisecond = std::floor(millisecond/10);
int second = int(std::floor(totaltime /1000) )% 60;
int minute = int(std::floor(totaltime/1000 /60)) % 60;
QString result = (minute<10 ? "0":"") + QString::number(minute)+":"+
(second<10 ? "0":"") + QString::number(second) + ":"+
(millisecond<10 ? "0":"")+QString::number(millisecond);
return result;
}
在main.cpp里实现多线程,实例化timerThread类,在实例化一个工作线程,把我们自己的类放入工作线程,启动工作线程即可.
同时我们需要qmlRegisterType
来注册我们的类,这样才能让QML文件知道要与这个文件通信
//注册计时线程,并将计时线程移动到工作线程
TimerThread timerThread;
QThread workerThread;
timerThread.moveToThread(&workerThread);
//启动工作线程
workerThread.start();
QQmlApplicationEngine engine;
qmlRegisterType<TimerThread>("com.timerthread",1,0,"TimerThread");
main.qml的修改,首先使用import倒入我们的timerThread类,这样我们就可以在qml中实例化,可以加上idimport com.timerthread 1.0
定义两个变量,接受我们信号发送的参数.发送的参数的作用域只在Connection里,所以需要外部变量来接收,方便我们的使用,
property bool isrunning: false
property string totaltime: ""
TimerThread{
id:timerThread
}
Connections{
target:timerThread
// 使用传递过来的 totaltime 参数,信号传递出来的参数在connect内部可以直接使用,在外部不行
onTimeUpdated:{
timerDisplay.text = totaltimestr
totaltime = totaltimestr
//console.log(totaltime)
}
onSig_isRunning:{
isrunning = isRunning
console.log(isRunning)
}
}
后边就将原来的一些变量替换为新接收的变量就行.
使用多线程的方式,定时器间隔取1也能精确计时,线程起到了作用
点击访问博客查看更多内容 |
---|