2010-07-27 10 views
5

Wie kann ich Benutzerinaktivität in einem Qt QMainWindow erkennen? Meine Idee ist bisher, einen QTimer zu haben, der einen Zähler erhöht, der, wenn ein bestimmter Wert überschritten wird, die Anwendung sperrt. Jede Maus- oder Schlüsselinteraktion sollte den Timer auf 0 zurücksetzen. Ich muss jedoch wissen, wie Eingangsereignisse richtig gehandhabt werden, die zurückgesetzt werden. Ich kann neu implementieren:Wie erkennt man Benutzerinaktivität in 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) 

... aber nicht die Ereignishandler aller Widgets in den QMainWindow Ereignisse verhindern in diesen Kontrollen auftreten von dem QMainWindow der zu erreichen? Gibt es eine bessere Architektur für die Erkennung von Benutzeraktivitäten?

Antwort

7

Sie können einen benutzerdefinierten Ereignisfilter verwenden, um alle von Ihrer Anwendung empfangenen Tastatur- und Mausereignisse zu verarbeiten, bevor sie an die untergeordneten Widgets übergeben werden.

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); 
    } 
} 

Dann etwas verwenden wie

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

Dies funktioniert auf jeden Fall (ich habe es selbst ausprobiert).

EDIT: Und vielen Dank an ereOn für den Hinweis, dass meine frühere Lösung nicht sehr nützlich war.

+0

Funktioniert gut, danke. Ich habe am Ende ein Signal mit dem obj-Parameter ausgegeben, wo du "resetMyTimer" hast, und jedes Fenster hat das Signal an seinen Reset-Timer-Slot angeschlossen, der überprüft, ob ein Widget in * diesem * Fenster das Ereignis generiert hat, so dass jedes Fenster unabhängig gesperrt wird von den anderen. –

+0

Das Ereignis wird anscheinend nur an eventFilter() gesendet, wenn keines der untergeordneten Widgets das Ereignis behandelt. Gibt es eine Möglichkeit, sicherzustellen, dass alle Ereignisse zu diesem Filter geleitet werden, bevor sie an anderer Stelle verarbeitet werden? – KyleL

0

Einer der besseren Ansatz wird sein, Xidle-Signal zu fangen, anstatt dann so viele Ereignisse vom Benutzer zu fangen. Hier muss man QEvent erfassen: MouseMove Event auch

Verwandte Themen