Re: QTimer within QThread
	
	
		You don't need the forever loop. You can always substitute it with a timer with a 0 timeout. I can't help you more based on what you posted because your code doesn't make much sense and it's hard to guess what you really wanted.
	 
	
	
	
		Re: QTimer within QThread
	
	
		Thank you for taking a look at this; unfortunately the actual code is intrinsically complex and I guess I haven't been successful in simplifying it for the question.
I don't quite understand how the forever{} loop can be substituted by a timer with a 0 timeout; can you point me to an example of this? I know about the trick of using a zero-second timer to manage GUI responsiveness in a single-thread application, but I expect you mean something different.
I'm using the forever{} loop because when I wrote this code I followed the Mandelbrot example in the Qt documentation, which is quite close to what I'm actually doing here. All I'm really trying to do is to add a single-shot QTimer within the rendering thread, so that the image updates itself after a certain interval. To be really precise, what I'm trying to do is to add a single short QTimer within the calculation thread which causes the image to update itself a certain time after the user stops interacting with the GUI; in other words, if the user does something with the GUI while the QTimer is still counting, the QTimer is meant to reset itself back to zero and start counting again.
	 
	
	
	
		Re: QTimer within QThread
	
	
		
	Quote:
	
		
		
			
				Originally Posted by 
Eos Pengwern
				
			 
			I don't quite understand how the forever{} loop can be substituted by a timer with a 0 timeout; can you point me to an example of this? I know about the trick of using a zero-second timer to manage GUI responsiveness in a single-thread application, but I expect you mean something different.
			
		
	 
 It's quite the same. The only difference is you want your "worker thread" to be "responsive" and not your "GUI thread".
The code you posted can be changed to:
	Code:
	
    Q_OBJECT
public slots:
    void loopIteration() {
        ...
            if (flagSet)
            {
                ud = new updater();
                unsetFlag();
            }
            ....
 
             if (anotherFlagSet)
             {
                 ud -> startSomething();
                 unsetTheOtherFlag();
             }
 
    }
};
 
thread.start();
Loop loop;
loop.moveToThread(&thread);
connect(&timer, SIGNAL(timeout()), &loop, SLOT(loopIteration());
timer.start(0);
timer.moveToThread(&thread); // optional
 
ServerLoop server;
server.moveToThread(&thread);
connect(&intervalTimer, ..., &server, ...);
intervalTimer.start(INTERVAL);
intervalTimer.mvoeToThread(&thread); // optional
 
But your code can be simplfied even more because your forever loop does nothing unless some flag is set. So you can implement slots for setting the flags that will do the task when they are requested.
	Code:
	
    Q_OBJECT
private slots:
  void createUpdater() {
    ud = new updater;
  }
  void executeStartSomething() {
    if(!ud) return;
    ud->startSomething();
  }
private:
  ...
};
 
thread.start();
DoItAll inASimpleWay;
connect(..., ..., &inASimpleWay, SLOT(createUpdater()));
connect(..., ..., &inASimpleWay, SLOT(startSomething()));
inASimpleWay.moveToThread(&thread);
 
and that's it. Instead of the two connect() statements you can use QMetaObject::invokeMethod() to trigger each of the methods on demand. It can even be a public method of the class itself:
	Code:
	
void DoItAll::raiseUpdaterFlag() {
  QMetaObject::invokeMethod(this, 
"createUpdater", Qt
::QueuedConnection);
 }
 
Then you can call it from any thread and it will work as expected.
	Code:
	
inASimpleWay.raiseUpdaterFlag();
 
	 
	
	
	
		Re: QTimer within QThread
	
	
		I think I'm slowly beginning to catch on... As it happens, I'm about to grab a few hours' sleep and then catch an 11-hour flight, but if my battery holds out I'll have a close look at this during the flight and, hopefully, home in on the solution.
Thank you again for your help.
	 
	
	
	
		Re: QTimer within QThread
	
	
		Fortunately my seat had a socket (ANA are good!), and by the time I had refactored my class without the forever{} loop, according to your second suggestion (using QMetaObject::invokeMethod as well) I'd got as far as St Petersburg (en route from Tokyo to London).
Anyway, it works now; the QTimer events within the thread are behaving just as they should.
I found two difficulties with QMetaObject::invokeMethod which added considerably to the size of the task:
- I found that the methods invoked did in fact need to be declared as actual slots: it wouldn't work if they were ordinary public methods.
- most of my methods took pointers as arguments, and QMetaObject::invokeMethod didn't seem to like that. I had to change things around to use const references instead. I also had be to be really careful to declare my custom structures with qRegisterMetaType, just like I would for a queued signal-slot connection.
Now, though, everything is working, so thank you very much.
	 
	
	
	
		Re: QTimer within QThread
	
	
		
	Quote:
	
		
		
			
				Originally Posted by 
Eos Pengwern
				
			 
			- I found that the methods invoked did in fact need to be declared as actual slots: it wouldn't work if they were ordinary public methods.
			
		
	 
 Yes. Or they have to be accompanied by the Q_INVOKABLE macro.
	Quote:
	
		
		
			- most of my methods took pointers as arguments, and QMetaObject::invokeMethod didn't seem to like that. I had to change things around to use const references instead. I also had be to be really careful to declare my custom structures with qRegisterMetaType, just like I would for a queued signal-slot connection.
			
		
	
 If you wanted all that to work across threads, you'd have to eventually do it anyway.