QT 线程:Getting QObject::startTimer: timers cannot be started from another thread 警告
Posted
技术标签:
【中文标题】QT 线程:Getting QObject::startTimer: timers cannot be started from another thread 警告【英文标题】:QT threads :Getting QObject::startTimer: timers cannot be started from another thread warning 【发布时间】: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( )
启动线程。
【问题讨论】:
【参考方案1】:问题是您在创建线程对象时由主线程隐式创建计时器。这是因为您的计时器是线程类的成员。
当您尝试启动计时器时,您是在不同的线程(run()
)中进行的,而不是在创建计时器的线程中,这会给您警告。
您需要在要运行它的线程中创建计时器:。将m_notificationTimer
在NotificcationThread
类中的声明从
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) 来确保您的信号和插槽在该线程上进行处理。
【讨论】:
文章链接移至blog.qt.digia.com/blog/2010/06/17/youre-doing-it-wrong以上是关于QT 线程:Getting QObject::startTimer: timers cannot be started from another thread 警告的主要内容,如果未能解决你的问题,请参考以下文章