
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:
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
class Loop : public QObject {
Q_OBJECT
public slots:
void loopIteration() {
...
if (flagSet)
{
ud = new updater();
unsetFlag();
}
....
if (anotherFlagSet)
{
ud -> startSomething();
unsetTheOtherFlag();
}
}
};
QThread thread;
thread.start();
QTimer timer;
Loop loop;
loop.moveToThread(&thread);
connect(&timer, SIGNAL(timeout()), &loop, SLOT(loopIteration());
timer.start(0);
timer.moveToThread(&thread); // optional
ServerLoop server;
server.moveToThread(&thread);
QTimer intervalTimer;
connect(&intervalTimer, ..., &server, ...);
intervalTimer.start(INTERVAL);
intervalTimer.mvoeToThread(&thread); // optional
To copy to clipboard, switch view to plain text mode
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.
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);
class DoItAll : public QObject {
Q_OBJECT
private slots:
void createUpdater() {
ud = new updater;
}
void executeStartSomething() {
if(!ud) return;
ud->startSomething();
}
private:
...
};
QThread thread;
thread.start();
DoItAll inASimpleWay;
connect(..., ..., &inASimpleWay, SLOT(createUpdater()));
connect(..., ..., &inASimpleWay, SLOT(startSomething()));
inASimpleWay.moveToThread(&thread);
To copy to clipboard, switch view to plain text mode
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:
void DoItAll::raiseUpdaterFlag() {
QMetaObject::invokeMethod(this,
"createUpdater", Qt
::QueuedConnection);
}
void DoItAll::raiseUpdaterFlag() {
QMetaObject::invokeMethod(this, "createUpdater", Qt::QueuedConnection);
}
To copy to clipboard, switch view to plain text mode
Then you can call it from any thread and it will work as expected.
inASimpleWay.raiseUpdaterFlag();
inASimpleWay.raiseUpdaterFlag();
To copy to clipboard, switch view to plain text mode
Bookmarks