QThread loop and QTimer
-
wrote on 12 Jul 2013, 13:57 last edited by
Hello to everyone,
I'm new in this forum: so please excuse me if my question is obvious.I'm trying to implement a GUI application. This app must call "Core" class, which is derived by QThread.
In the Core class there is an infinite loop. There is also a timer: its timeout signal is calling a Core's slot.
This is a sample of my code:@
class Core : public QThread
{
Q_OBJECTprivate:
QTimer * timer;
volatile bool flag;public:
Core(QObject *parent = 0);
~Core();protected:
void run(void);public slots:
void TimerTick(void);
}// Implementation
Core::Core( QObject *parent)
: QThread(parent)
{
this->flag = false;
this->timer = new QTimer();
this->timer->setInterval(10);
this->timer->moveToThread(this);
QObject::connect(this->timer, SIGNAL(timeout()), this, SLOT(TimerTick()));
QObject::connect(this, SIGNAL(started()), this->timer1ms, SLOT(start()));
}void Core::TimerTick(void)
{
flag = true;
}void Core::run(void)
{
while(!flag)
{
// main thread loop code
}
}
@My program doesn't call the slot method TimerTick()
Can anybody help me?Thanks in advance
-
Hi and welcome to devnet,
Your thread doesn't run an event loop so your timer won't run thus the slot will not get called.
You should rather have that timer outside of your class if you really want to use your thread with a never ending loop.
Since you're at the design stage, are you sure that the infinite loop is the way to go ?
Hope it helps
-
wrote on 12 Jul 2013, 14:16 last edited by
BTW deriving from QThread is highly discouraged!! The QThread is designed as a wrapper around a QObject derived class.
Read this forum:
"How to do threads in Qt":http://mayaposch.wordpress.com/2011/11/01/how-to-really-truly-use-qthreads-the-full-explanation/
That object will then run in a different event loop, so start your timer there and send signals or overwrite the timerEvent and do stuff in there. Maybe QBasicTimer is easier to use with the timerEvent. -
Jeroentje@home
Wrapper vs derivation has been brought up several times in the last few months (here and on the mailing list)After some (sometimes heated) conversations, the final point made was: it depends on the use case. (That's why I also asked the OP for here reason to do an infinite loop) Most of the time using a wrapper is the way to go, but that's not always the case.
-
wrote on 12 Jul 2013, 15:10 last edited by
Thank you so much for your quick replies.
I'd like to use an infinite loop because i want to simulate on a desktop pc an embedded firmware, which is composed by an infinite main loop and a timer with its interrupt. -
wrote on 12 Jul 2013, 16:00 last edited by
Now I'm using the QThread as a wrapper and not as a Base Class.
@
/*** main function /
QThread * thread = new QThread();
Core * pCore = new Core();
pCore->moveToThread(thread);
QObject::connect(thread, SIGNAL(started()), pCore, SLOT(CoreStart()));
thread->start();
/****************/class Core : public QObject { Q_OBJECT private: QTimer * timer; volatile bool flag; public: Core(QObject *parent = 0); ~Core(); private: void run(void); public slots: void CoreStart(); private slots: void TimerTick(void); } // Implementation Core::Core( QObject *parent) : QObject(parent) { this->flag = false; } void Core::CoreStart(void) { // the thread affinity of timer is my thread this->timer = new QTimer(); this->timer->setInterval(10); QObject::connect(this->timer, SIGNAL(timeout()), this, SLOT(Timer_Tick())); while(!flag) { // loop code } } void Core::TimerTick(void) { flag = true; }
@
Now I think that I need to implement an event loop for my thread. Is it possible?
Otherwise, i must put my timer outside the Core class: in this case how can i emit some signal to the Core class infinite loop?Thanks
-
Essentially, an event loop IS an infinite loop. It cannot coexist with another infinite loop on the same thread.
[quote author="aenima1891" date="1373641819"]I'd like to use an infinite loop because i want to simulate on a desktop pc an embedded firmware, which is composed by an infinite main loop and a timer with its interrupt.
[/quote]Qt is an event-driven framework -- the event loop can easily produce periodic "interrupts". Something like this:@
// Class header
class Core : public QObject {
Q_OBJECTpublic:
Core(QObject* parent = 0);public slots:
void interrupt();
};
@@
// Program
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Core core;
QTimer timer;// Invoke interrupt() whenever the timer fires QObject::connect(&timer, SIGNAL(timeout()), &core, SLOT(interrupt())); // Fire the timer every 1 second timer.start(1000); // Start the event loop return a.exec()
}
@And if Core::interrupt() is a short function, you can run your simulation in the main thread alongside the GUI, networking, etc.
-
wrote on 12 Jul 2013, 16:46 last edited by
Thanks JKSH.
Can I add a QEventLoop to my thread and insert a call QEventLoop::exec() inside my "thread loop"? This should force the code to reenter the event loop and so manage the signal emitted by the timer.@
while(!flag)
{
// thread looop
loop.exec();
}
@Is it possible?
-
[quote author="aenima1891" date="1373647595"]Thanks JKSH.[/quote]You're welcome :)
[quote]Can I add a QEventLoop to my thread and insert a call QEventLoop::exec() inside my "thread loop"?[/quote]No. QEventLoop::exec() is a blocking function.Like I said before, an event loop is an infinite loop. If you nest an infinite loop inside another infinite loop, the outer one will only run once. And if you break out of your event loop, your timer signals will get lost.
Try writing your simulation without the infinite while loop.
-
Could you show us a bit of your infinite loop code ? That would allow us to give you better hints on how to implement your simulation
3/10