QT线程:获取QObject :: startTimer:无法从另一个线程警告启动计时器

时间:2011-06-06 12:39:41

标签: c++ qthread

我按照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();
}

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

3 个答案:

答案 0 :(得分:13)

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

当你尝试启动计时器时,你会在另一个线程(run())中,而不是在创建计时器的线程中,这会给你警告。

您需要在要运行它的线程中创建计时器:更改m_notificationTimer课程中NotificcationThread的声明

QTimer m_NotificationTimer;

QTimer* m_NotificationTimer;

并使用

run()中创建计时器
m_NotificationTimer = new QTimer(this);
m_NotificationTimer->setInterval(interval);
m_NotificationTimer->start();

答案 1 :(得分:8)

如果添加行

m_NotificationTimer.moveToThread(this);

从你的计时器对象上的那个点开始的 run()方法将调用你线程中的连接插槽。

首次创建计时器时,它将在主线程中运行。通过将其移动到您自己的线程,moveToThread方法将更改计时器对象的线程关联。

答案 2 :(得分:3)

值得一提的是article

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