ZBLOG

RadarSpeed::RadarSpeed(QObject *parent) : QObject(parent) { m_pTimer = new QTimer(this); connect(m_pTimer, &QTimer::timeout, this, &RadarSpeed::onTimeout); m_bTimerIsRunning = false; } void RadarSpeed::startTimer(int iTime) { ...

根据您提供的代码和错误信息,出现 QObject::startTimer: Timers cannot be started from another thread 的原因是你在非主线程中尝试启动一个 QTimer。这种情况通常发生在以下几种情形:

  1. 接收数据的信号是在工作线程中触发:如果 recvData 函数是在一个工作线程(即非 GUI 线程)中被调用,而这个函数内部调用了 this->startTimer(m_iStopSignalTime);,那么会导致上述错误。

  2. QTimer 的生命周期:虽然你将 QTimer 的父对象设置为当前 QObject(也就是 RadarSpeed),但如果该 QObject 本身是在非主线程创建或运行,那么所有与之相关联的定时器操作也必须在主线程进行。

解决方法

为了避免这个问题,你可以通过以下方式确保定时器只在主线程中启动:

  1. 使用信号槽机制: 如果 recvData 是在工作线程中处理的,可以发射一个信号并连接到主线程中的槽,这样可以安全地启动计时器。
   // 在RadarSpeed类内定义信号
   signals:
       void startTimerSignal(int iTime);
   
   // 在构造函数中连接信号和槽
   connect(this, &RadarSpeed::startTimerSignal, this, &RadarSpeed::startTimer);

   // 修改recvData函数
   void RadarSpeed::recvData(const QByteArray &data)
   {
       if(data.size() == 6)
       {
           int HH = (unsigned char)data[1];
           int LL = (unsigned char)data[2];
           int XX = (unsigned char)data[3];
           speed = HH * 256 + LL + (float)XX / 100.0;
           m_speed = speed;

           if(m_speed > 0.0)
           {
               // ...其他逻辑...
               
               if(m_bTimerIsRunning)
               {
                   qDebug() << __LINE__ << "RadarSpeed_out timer stop ";
                   this->stopTimer();
               }
           }
           else
           {
               if(m_tempStart)
               {
                   qDebug() << __LINE__ << "RadarSpeed_out timer start 5 s ";
                   emit startTimerSignal(m_iStopSignalTime); // 发射信号,要求启动计时器
                   m_tempStart = false;
               }
           }
       }
   }
  1. 确保 recvData 在正确的上下文中被调用

    • 检查您的代码,确认 recvData 方法是否在正确的线程环境下被调用。如果它是由某个其他对象的槽触发的,请确保该对象处于主线程。
  2. 使用 Qt 提供的事件循环机制: 如果你希望从子线程执行 GUI 操作,可以考虑使用 Qt 的事件队列,将任务发送到主线程。例如,使用 QMetaObject::invokeMethod() 来调度定时器启动。

示例代码如下:

#include <QMetaObject>

void RadarSpeed::recvData(const QByteArray &data)
{
    if(data.size() == 6)
    {
        // 数据处理...
        
        if(m_tempStart)
        {
            qDebug() << __LINE__ << "RadarSpeed_out timer start 5 s ";
            QMetaObject::invokeMethod(this, "startTimer", Qt::QueuedConnection, Q_ARG(int, m_iStopSignalTime));
            m_tempStart = false;
        }
    }
}

通过这些方式,你应该能成功避免 QObject::startTimer: Timers cannot be started from another thread 的错误。


内容由零声教学AI助手提供,问题来源于学员提问

本站部分文章来源于网络,版权归原作者所有,如有侵权请联系站长删除。
转载请注明出处:https://sdn.0voice.com/?id=7163

分享:
扫描分享到社交APP
上一篇
下一篇
发表列表
游客 游客
此处应有掌声~
评论列表

还没有评论,快来说点什么吧~

联系我们

在线咨询: 点击这里给我发消息

微信号:3007537140

上班时间: 10:30-22:30

关注我们
x

注册

已经有帐号?