I follow the examples from the Qt SDK, starting timer in the QThread
Subclass
but I keep getting the 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 start the Thread from the main GUI with Execute( )
.
The problem is that you create the timer implicitly by the main thread when you create your thread object. This is because your timer is a member of your thread class.
When you try to start the timer, you do in a different thread (in run()
), not in the thread where the timer was created, which gives you the warning.
You need to create the timer in the thread where you want to run it:. Change the declaration of m_notificationTimer
in your NotificcationThread
class from
QTimer m_NotificationTimer;
to
QTimer* m_NotificationTimer;
and create the timer in run()
with
m_NotificationTimer = new QTimer(this);
m_NotificationTimer->setInterval(interval);
m_NotificationTimer->start();
It is also worth mentioning this article
The biggest adjustment for me was to understand that threads in qt are used as an interface, and are not really intended for subclassing. With that being said, I would keep your class and and actual QThread separate. And then just use YourClass.moveToThread( &YourQtThread) to ensure your signals and slots are process on that thread.
If you add the line
m_NotificationTimer.moveToThread(this);
to beginning of run() method of your thread from that point on your timer object will invoke the connected slot within the your thread.
When you first create the timer it will run within your main thread. By moving it to your own thread as above the moveToThread method will change the thread affinity of the timer object.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With