菜鸡小王,在线学编程 2024-09-21 17:00 采纳率: 50%
浏览 6

QT 定时器 lambda表达式

代码如下,这里是想写定时器按照设定时间执行时序操作,但是每次执行的时间与预设时间不符和,只有第一次执行时40多秒,再次执行时时间就会变短。请教一下是什么原因,该如何解决呢?

    QTimer *TestTimer = new QTimer(this);
    TestTimer->setTimerType(Qt::PreciseTimer);

    cntnum = 0;
    connect(TestTimer,
            &QTimer::timeout,
            this,
            [=](){
        TestTimer->stop();
        TestTimer->start(10);
        cntnum++;
        //逻辑时序
        if(cntnum < 4800)
        {
            //发送配置命令
            if(cntnum == 10)
            {

            }
            else if(cntnum == 20)
            {

            }
            else if(cntnum == 30)
            {

            }
            else if(cntnum == 40)
            {

            }
            else if(cntnum == 50)
            {

            }
            else if(cntnum == 60)
            {
            }
            else if(cntnum == 100)
            {
            }
            else if(cntnum == 550)
            {
            }
            else if(cntnum == 600)
            {
            }
            else if(cntnum == 4600)
            {
               //发送指令等
            }
            else if(cntnum == 4700)
            {
               //发送指令等
            }
            else if(cntnum == 4750)
            {
                TestTimer->stop();

                //执行数据解析之类的耗时操作
                TestTimer->start(10);
            }
            else
            {

            }

        }
        else//测试结束
        {
        }

    });
    TestTimer->setSingleShot(false);
    TestTimer->start(10);

  • 写回答

2条回答 默认 最新

  • 一轮明月照丘壑 2024-09-21 17:01
    关注

    以下回复参考:皆我百晓生券券喵儿等免费微信小程序作答:

    你的问题可能是由于计时器的计时方式和Qt计时器的精度问题导致的。Qt的QTimer是基于事件循环的,这意味着它的计时可能受到事件循环处理速度的影响。在某些情况下,事件循环处理其他任务可能会导致计时器的计时时间短暂偏移。然而,你提到的偏移可能是明显的超出了这种微小的波动范围。这可能是由于以下原因造成的:

    1. 你使用了多次start()方法,这可能导致定时器中断后重新计算时间,使得定时器实际间隔小于设定的时间间隔。你可以尝试在每次定时器触发后使用单次触发模式(setSingleShot(true)),然后在定时器触发后再次启动定时器以解决这个问题。此外,如果你希望在每次触发后立即重新启动定时器,你不需要调用start(),因为定时器默认会在每次触发后立即重新启动。所以你可以移除那些不必要的start()调用。你的代码应该如下修改:
    QTimer *TestTimer = new QTimer(this);
    TestTimer->setTimerType(Qt::PreciseTimer);
    TestTimer->setSingleShot(false); //设置为非单次触发模式
    connect(TestTimer, &QTimer::timeout, this, [=]() {
        TestTimer->stop(); // 在定时器触发后停止定时器
        cntnum++;
        //你的逻辑时序代码...
        TestTimer->start(10); // 在逻辑处理完成后重新启动定时器
    });
    TestTimer->start(10); // 启动定时器
    

    注意,上述代码假设你的逻辑时序代码可以在一个timeout事件内完成。如果你的逻辑时序代码非常耗时,可能会阻塞事件循环并导致定时器不准时。在这种情况下,你可能需要将耗时的操作移到另一个线程中执行。

    如果你发现你的定时器依然不准确,你可以考虑使用更精确的计时器类型,例如高精度定时器(High-resolution Timer)。但请注意,这些计时器可能受到操作系统和硬件的限制。此外,你也可以尝试使用系统时钟的校准工具来校准你的系统时钟以获取更准确的计时结果。

    评论

报告相同问题?

问题事件

  • 创建了问题 9月21日

悬赏问题

  • ¥15 如何在vue.config.js中读取到public文件夹下window.APP_CONFIG.API_BASE_URL的值
  • ¥50 浦育平台scratch图形化编程
  • ¥20 求这个的原理图 只要原理图
  • ¥15 vue2项目中,如何配置环境,可以在打完包之后修改请求的服务器地址
  • ¥20 微信的店铺小程序如何修改背景图
  • ¥15 UE5.1局部变量对蓝图不可见
  • ¥15 一共有五道问题关于整数幂的运算还有房间号码 还有网络密码的解答?(语言-python)
  • ¥20 sentry如何捕获上传Android ndk 崩溃
  • ¥15 在做logistic回归模型限制性立方条图时候,不能出完整图的困难
  • ¥15 G0系列单片机HAL库中景园gc9307液晶驱动芯片无法使用硬件SPI+DMA驱动,如何解决?