2010-07-27 2 views
5

Как я могу обнаружить неактивность пользователя в Qt QMainWindow? Моя идея до сих пор заключается в том, чтобы иметь QTimer, который увеличивает счетчик, который, если определенное значение передается, блокирует приложение. Любое взаимодействие с мышью или ключом должно установить таймер на 0. Однако мне нужно знать, как правильно обрабатывать события ввода, которые перезагружаются; Я могу повторно реализовать:Как обнаружить неактивность пользователя в Qt?

virtual void keyPressEvent(QKeyEvent *event) 
virtual void keyReleaseEvent(QKeyEvent *event) 
virtual void mouseDoubleClickEvent(QMouseEvent *event) 
virtual void mouseMoveEvent(QMouseEvent *event) 
virtual void mousePressEvent(QMouseEvent *event) 
virtual void mouseReleaseEvent(QMouseEvent *event) 

... но не обработчики событий всех виджетов в QMainWindow предотвратить события, происходящие в этих контролей от достижения QMainWindow-х? Есть ли лучшая архитектура для обнаружения активности пользователя, какой она есть?

ответ

7

Вы можете использовать специальный фильтр событий для обработки всех событий клавиатуры и мыши, полученных вашим приложением, прежде чем они будут переданы дочерним виджетам.

class MyEventFilter : public QObject 
{ 
    Q_OBJECT 
protected: 
    bool eventFilter(QObject *obj, QEvent *ev) 
    { 
    if(ev->type() == QEvent::KeyPress || 
     ev->type() == QEvent::MouseMove) 
     // now reset your timer, for example 
     resetMyTimer(); 

    return QObject::eventFilter(obj, ev); 
    } 
} 

Затем используйте что-то вроде

MyApplication app(argc, argv); 
MyEventFilter filter; 
app.installEventFilter(&filter); 
app.exec(); 

Это, безусловно, работает (я пробовал сам).

EDIT: И большое спасибо ereOn за указание, что мое раннее решение было не очень полезно.

+0

Отлично работает, спасибо. Я закончил тем, что излучал сигнал с параметром obj, где у вас есть «resetMyTimer», и каждое окно прикрепляло сигнал к слоту таймера сброса, который проверяет, не виден ли виджет в * этом * окне, поэтому каждое окно блокируется независимо других. –

+0

Событие, по-видимому, отправляется только eventFilter(), если ни один из дочерних виджетов не обрабатывает указанное событие. Есть ли способ обеспечить, чтобы все события переходили в этот фильтр, прежде чем обрабатываться в другом месте? – KyleL

0

Один из лучших подходов заключается в том, чтобы поймать сигнал с привязкой, а не захватывать так много событий от пользователя. Здесь нужно захватить QEvent: событие MouseMove также