emit SIGNAL when GUI Thread is idle in Qt?
c++, qt
Solution
QAbstractEventDispatcher allows one to plug their own events into Qt's event loop. Also it allows to monitor event loop's workload.
Here is an example. The widget is listening for QAbstractEventDispatcher::awake() and QAbstractEventDispatcher::aboutToBlock() signals to know when event loop is busy.
#include <QtGui>
class IdleAwareWidget : public QWidget
{
Q_OBJECT
public:
IdleAwareWidget(QWidget *parent = 0) : QWidget(parent) {
dispatcher = QAbstractEventDispatcher::instance();
connect(dispatcher, SIGNAL(awake()), SLOT(awake()));
connect(dispatcher, SIGNAL(aboutToBlock()), SLOT(aboutToBlock()));
}
private slots:
void awake() {
lastAwake = QTime::currentTime();
qDebug() << "Slept for " << lastBlock.msecsTo(lastAwake) << " msec";
}
void aboutToBlock() {
lastBlock = QTime::currentTime();
qDebug() << "Worked for " << lastAwake.msecsTo(lastBlock) << " msec";
}
private:
QAbstractEventDispatcher *dispatcher;
QTime lastAwake;
QTime lastBlock;
};
main.cpp:
#include <QtGui>
#include "idle_widget.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
IdleWidget widget;
widget.show();
return a.exec();
}
If the question is just about idle processing, then QTimer with 0 interval is an option:
QTimer::singleShot(0, this, SLOT(doWorkInIdle()));
This will schedule call to `doWorkInIdle()` slot as soon as the event loop goes to idle state. Splitting work to small chucks won't block the loop and application will remain responsive.
Problem
I have GUI Thread which creates & manages the GUI content. Now when the application is idle i.e. all threads are idle (or even if only the GUI thread is idle) then I want my `QMainWindow` inherited class's object to emit a `SIGNAL`. So that whenever the Application is idle I will silently create the `Widgets` required for the next stage. So I would like to know how do I make that object to emit a `SIGNAL` whenever the GUI Thread is idle? My Application is multi-threaded & has multiple classes, so it is not necessary that the `SIGNAL` is emitted in the GUI class only. Also the `SIGNAL` should not be emitted as soon as the thread becomes idle. I want that the thread should be idle for a sufficient amount of time so that I am sure that the user is actually idling. Thank You!