QT topics: getting QObject :: startTimer: timers cannot be started from another thread

I follow the examples from the Qt SDK, starting a timer in a subclass of QThread but I keep getting a warning and the thread never starts the timer. Here is the code:

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

I am running Thread from the main GUI using Execute( ) .

+6
source share
3 answers

If you add a line

 m_NotificationTimer.moveToThread(this); 

At the beginning of the run () method of your thread, a connected slot inside your thread is called from this point in your timer object.

When you first create a timer, it will work inside your main thread. By moving it to its own thread, as described above, moveToThread will change the affinity of the timer object thread.

+7
source

The problem is that you create a timer implicitly by the main thread when creating the stream object. This is because your timer is a member of your thread class.

When you try to start the timer, you make another thread (in run() ), and not in the thread where the timer was created, which gives you a warning.

You need to create a timer in the stream where you want to start it :. Modify the m_notificationTimer in your NotificcationThread class from

 QTimer m_NotificationTimer; 

to

 QTimer* m_NotificationTimer; 

and create a timer in run() with

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

Also worth noting is the article.

The biggest setup for me was the understanding that the threads in qt are used as an interface and are not really intended to be a subclass. With that said, I would keep your class and actual QThread separate. And then just use YourClass.moveToThread (& YourQtThread) to ensure that your signals and slots are processed in this thread.

+2
source

Source: https://habr.com/ru/post/889866/


All Articles