PDA

View Full Version : Detecting user inaction



jrideout
26th March 2006, 13:27
In Qt4, does anybody have a good idea of how determine if there is no user interaction with a program?

I'd like to have a have a signal emited if the user has been inactive for x minutes. I was thinking I could have a single shot qtimer that is reset after any user event, by a installEventFilter function for the qmainwindow. Would this work? Is it the best solution. I wanted to get some advice before I ran off and spent a bunch of time playing. Thanks.

jacek
26th March 2006, 13:39
You might try to install an event filter for QApplication to monitor all events.

jrideout
27th March 2006, 05:00
Thanks, so I went with my original idea with jacek's suggestion of using the qapp rather than the main window, but the solution should be generic. Here is an example for anyone that might want to use a similar code.

Header


#include <QtGui>
#include <QtCore>

class activityFilter : public QObject
{
Q_OBJECT
Q_PROPERTY(int interval READ interval WRITE setInterval)
public:
activityFilter(QObject *parent = 0);
int interval () const { return _interval; };
void setInterval ( int msec ) { _interval = msec; };
signals:
void userInactive();
public slots:
void timeout();
protected:
bool eventFilter(QObject *obj, QEvent *event);
private:
QTimer *timer;
int _interval;
};


Implementation


#include <QtGui>
#include <QtCore>
#include "af.h"

activityFilter::activityFilter(QObject *parent) : QObject(parent), _interval(3000)
{
timer = new QTimer(this);
timer->start(_interval);
connect(timer, SIGNAL(timeout()), this, SLOT(timeout()));
}

bool activityFilter::eventFilter(QObject *obj, QEvent *event)
{
if (event->type() != QEvent::Timer) // this is needed or else the timer is reset by its own timeout signal event before the signal is sent
timer->start(_interval);
return QObject::eventFilter(obj, event); // just a wrapper, we don't want to override any events
}

void activityFilter::timeout()
{
qDebug() << "user timeout";
emit userInactive();
}


Example


#include <QtGui>
#include <QtCore>
#include "ui_main.h"
#include "af.h"

int main(int argc, char * argv[])
{
QApplication app(argc, argv);
app.setQuitOnLastWindowClosed(true);

activityFilter *ef;
ef = new activityFilter(&app);
app.installEventFilter(ef);

QDialog win;
Ui_dialog ui;
ui.setupUi(&win);

QObject::connect(ef, SIGNAL( userInactive() ),
&win, SLOT( close() ));

win.show();
return app.exec();
}


I created a quick dialog in designer saved as main.ui to make this work.

vasanth
24th September 2007, 11:58
hi man

cool solution

thanks a lot to u


by:)e

winifredrayen
9th December 2010, 18:46
@jrideout cool , thanks for the solution. I had a doubt while was i looking through ur code. If the filter object is "ef" and the monitored object is our "app" then the event monitoring is done across our app only right ? if we had to deal with idle time of the entire mobile then we need to monitor the parent process or say the main standby process isnt it ? can you brief on that ?

winifredrayen
10th December 2010, 07:37
cool , thanks for the solution. I had a doubt while was i looking through ur code. If the filter object is "ef" and the monitored object is our "app" then the event monitoring is done across our app only right ? if we had to deal with idle time of the entire mobile then we need to monitor the parent process or say the main standby process isnt it ? can you brief on that