PDA

View Full Version : QTimer don't start



Qn00b
5th February 2011, 17:01
Hi

I have a problem with QTimer, I call the start function but don't work:



class MyClass : public QObject {

Q_OBJECT

private:
QTimer* timer;

private slots:
void executeMyTimer();

....
};




MyClass::MyClass() : QObject() {
this->timer = new QTimer(this);
this->timer->setInterval(500);
connect(this->timer, SIGNAL(timeout()), this, SLOT(executeMyTimer()));
this->timer->start();
}


I've tried to use QBasicTimer, QTimer::singleShot() and QObject::startTimer() but don't work...

I think that the problem is that my app have an infinite loop. I call the run() function like this:



int main(int argc, char** argv) {
QApplication app(argc, argv);

MyApp app;
QTimer::singleShot(0, &app, SLOT(run()));

return app.exec();
}


And the run function:


MyApp::run() {
// .....

for(;;) {
// ...
}
}


Somebody can help me please?

nirva
5th February 2011, 20:42
An infinite loop would definitely be a problem. QTimer will fire only when the execution of the program is in an event loop, it can't interrupt infinite loops. Why do you have the infinite loop anyway?

ChrisW67
5th February 2011, 20:58
I assume you instantiate your MyClass somewhere inside run(). You could use QCoreApplication::processEvents() inside your loop to give the timer signals a chance to be processed. I suspect rethinking the design would a better place to put some effort.

Qn00b
5th February 2011, 21:58
Hi! Thank you very much for your help!


I assume you instantiate your MyClass somewhere inside run()

Yes.


Why do you have the infinite loop anyway?

I need to read hardware events... For example, is similar to read keys, you need to listen the keyboard all time and process the key pressed.


You could use QCoreApplication::processEvents() inside your loop to give the timer signals a chance to be processed.

No, this don't work because the function to read keys (as in the example) blocks the Qt event loop.


I will try to launch the infinite loop in other thread, although I think that isn't the best solution..

Any other idea?
Thanks!

john_god
5th February 2011, 22:30
Can't you just forget about the infinite loop and use keypressevent() to read the keyboard, or am I missing something ?

Qn00b
5th February 2011, 22:42
No I can't. Really the application don't read keys, is an example of the problem.

I have a non Qt function to catch hardware events that blocks the Qt event loop and disallow me to use timers...

Thanks!

squidge
5th February 2011, 23:36
If your writing this on Windows, then you can have workable timers without an event loop - Windows will call your application code directly, bypassing any infinite loop you have in your code. However, if your timer function is too long, it can have disastrous consequences on the OS.

Qn00b
5th February 2011, 23:46
No, I need to develop it for GNU/Linux... And confirmed, launch the infinite loop in a thread crash the application (I use a C library and don't support threads...)

Anyway thank you very much!!

wysota
6th February 2011, 21:38
Read this article, maybe it will give you some insight: Keeping the GUI Responsive.

Qn00b
7th February 2011, 00:24
I try all methods, none worked...

I will try to explain in detail the problem...
I have a class with a run() method and a static callback method. The callback method is called when detects a change in hardware:


int main(int argc, char** argv) {
QApplication app(argc, argv);

HWHandler hwh;
QTimer::singleShot(0, &hwh, SLOT(run()));
// I have also tested -> hwh.start();

return app.exec();
}



class HWHandler { // I have also tested -> : public QThread
public:
void run();
static void ProcessHwEvent();
};




void HWHandler::run() {
forever {
if(waitHWEvent()) // This function returns ONLY when a HW event occurs, if no hw event, no return and freeze the Qt event loop
getHWEvent(); // Calls to ProcessHwEvent() that process the HW event
}
}


And in ProcessHwEvent() I call to another class that uses QTimers... QTimer that don't work...


I try to put the run() code in a thread, but the Qt event loop continuous frezee...
Any idea for what the Qt event loop is freeze?
Any solution?

Thanks!

ChrisW67
7th February 2011, 04:27
Why not have your blocking thread just queue a signal to the main GUI thread when something changes and continue the processing there? That is, getHwEvent just collects some information and emits a suitable queued signal that is connected to a slot in the main thread.

What is this blocking hardware change function in a Linux environment?
Why is ProcessHwEvent() static?

nirva
7th February 2011, 07:44
And in ProcessHwEvent() I call to another class that uses QTimers... QTimer that don't work...
I don't think you can/should use QTimers in ProcessHwEvent() because it's still a part of the infinite loop. Even if you put the loop in another thread (which you should do) any QTimer object you create is going to live in the wrong thread unless you move it to the main thread with QObject::moveToThread().


I try to put the run() code in a thread, but the Qt event loop continuous frezee...
Any idea for what the Qt event loop is freeze?
Any solution?

Can you show the code? Because you're not giving us much information I'm guessing that you made HWHandler::run() public and called it directly from the main thread.

Qn00b
7th February 2011, 09:57
Hi! Finally I have been able to solve the problem! I put the infinite loop in a thread and I have made that ProcessHwEvent() sends signals to other class. With signals all is ok, the problem was that I called directly to other functions.

Thanks very much to all!!

wysota
7th February 2011, 23:02
You might have read the article and you might have "tried everything" but you didn't follow any of the advices from the article.

The easiest solution to your "problem" is to avoid calling waitHWEvent() which I bet is possible using solution such as QSocketNotifier or something similar. Using threads is a "sort-of" solution to the "problem" but in reality it doesn't solve the problem just works around it in some of the cases. My immediate question is how do you exit the thread if you want to finish the program? With your current "solution" the only thing you can do is to kill it the hard way.