当前位置: 首页 > article >正文

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也能精确计时,线程起到了作用

点击访问博客查看更多内容

http://www.kler.cn/a/310679.html

相关文章:

  • mysql 快速解决死锁方式
  • 如何线程安全的使用HashMap
  • 手动实现h5移动端点击全屏按钮横屏展示图片,左右滑动切换,处理页面会随着手指滑动问题
  • KubeVirt入门介绍
  • Android 开发指南:初学者入门
  • Java面试要点02 - 自动装箱与拆箱的原理与性能解析
  • 【算法】堆与优先级队列
  • shinyproxy部署R语言shiny APP
  • C++:字符串string转成整型int
  • 数据结构一:绪论
  • linux-系统管理与监控-日志管理
  • 本地不能訪問linux的kafka服務
  • 研1日记14
  • 【数据结构】排序算法---冒泡排序
  • 【JVM GC核心参数】JVM原理,JAVA 各种垃圾回收器的核心参数,JAVA GC回收器参数配置,核心参数说明
  • 二百六十四、Java——Java采集Kafka主题A的JSON数据,解析成一条条数据,然后写入Kafka主题B中
  • 数组学习内容
  • Agent:原理与快速构建 | 人工智能 | Langchain | Python ——学习笔记
  • 使用 Fairseq 进行音频预训练:配置与实现
  • 设计模式之命令模式:从原理到实战,深入解析及源码应用
  • xml中SQL执行错误(使用另外一张表的两个字段,组装SQL的where查询条件)
  • 阿里巴巴搜索API返回值:电商市场竞争的新武器含
  • 动态规划---回文子串
  • 55 mysql 的登录认证流程
  • 掌握MATLAB中的数据类型转换技巧
  • 21. 什么是MyBatis中的N+1问题?如何解决?