【问题标题】:QT threads :Getting QObject::startTimer: timers cannot be started from another thread warningQT 线程:Getting QObject::startTimer: timers cannot be started from another thread 警告
【发布时间】:2011-09-09 06:39:12
【问题描述】:

我遵循 Qt SDK 中的示例,在 QThread 子类中启动计时器 但我不断收到警告,线程永远不会启动计时器。 代码如下:

NotificationThread::NotificationThread(QObject *parent)
           :QThread(parent),
           m_timerInterval(0)
{
 moveToThread(this);
}


NotificationThread::~NotificationThread()
{
 ;
}

void NotificationThread::fire()
{
  WRITELOG("A::fire called -- currentThread:" + QString::number((int)currentThread()->currentThreadId()));
  QVector<StringPer>* batchVectorResult = new QVector<StringPer>();   
  emit UpdateGroupNotifications(batchVectorResult);

}

void NotificationThread::run()
{

      connect(&m_NotificationTimer, SIGNAL(timeout()),
              this,SLOT(fire(),Qt::DirectConnection));

      WRITELOG("A::run() worker thread -- currentThread:" + QString::number((int)currentThread()->currentThreadId()));
   //SetNotificationTimerFromConf();
   QVariant val(ConfigSettings::getInstance()->ReadFromSettingsReturnVariant(SETTINGS_KEY_NOTIFICATIONTHREAD));
   int interval = val.toInt();
   m_NotificationTimer.setInterval(interval);
      m_NotificationTimer.start();

      QThread::exec();
}


void NotificationThread::SetNotificationTimerFromConf()
{
 QVariant val(ConfigSettings::getInstance()->ReadFromSettingsReturnVariant(SETTINGS_KEY_NOTIFICATIONTHREAD));
 int interval = val.toInt();
 m_NotificationTimer.setInterval(interval);
}


void NotificationThread::UpdateNotificationTimerRT(int timerInterval)
{
 m_NotificationTimer.setInterval(m_timerInterval);
}


void NotificationThread::Execute(const QStringList batchReqList)
{
 QVector<QString>* batchVectorResult = new QVector<QString>();   
 start();
}

我从主 GUI 使用 Execute( ) 启动线程。

【问题讨论】:

    标签: c++ qthread


    【解决方案1】:

    问题是您在创建线程对象时由主线程隐式创建计时器。这是因为您的计时器是线程类的成员。

    当您尝试启动计时器时,您是在不同的线程(run())中进行的,而不是在创建计时器的线程中,这会给您警告。

    您需要在要运行它的线程中创建计时器:。将m_notificationTimerNotificcationThread 类中的声明从

    QTimer m_NotificationTimer;
    

    QTimer* m_NotificationTimer;
    

    并在run() 中创建计时器

    m_NotificationTimer = new QTimer(this);
    m_NotificationTimer->setInterval(interval);
    m_NotificationTimer->start();
    

    【讨论】:

    • 或者只使用一个初始化列表: class MyClass: public QObject { Q_OBJECT public: MyClass() : m_thread(this) {} QTimer m_timer; }
    【解决方案2】:

    如果添加行

    m_NotificationTimer.moveToThread(this);
    

    到您的线程的 run() 方法的开始,从您的计时器对象上的那一点开始,将调用您线程中的连接槽。

    当您第一次创建计时器时,它将在您的主线程中运行。通过将其移动到您自己的线程上,moveToThread 方法将更改计时器对象的线程亲和性。

    【讨论】:

      【解决方案3】:

      这个article也值得一提

      对我来说最大的调整是了解 qt 中的线程被用作接口,而不是真正用于子类化。话虽如此,我会让你的班级和实际的 QThread 分开。然后只需使用 YourClass.moveToThread( &YourQtThread) 来确保您的信号和插槽在该线程上进行处理。

      【讨论】:

      猜你喜欢
      • 2022-12-02
      • 2015-01-23
      • 1970-01-01
      • 2017-01-11
      • 2014-04-19
      • 2014-02-23
      • 2011-03-25
      • 1970-01-01
      • 2022-10-04
      相关资源
      最近更新 更多