簡體   English   中英

如何檢測 Qt 中的用戶不活動?

[英]How to detect user inactivity in Qt?

如何檢測 Qt QMainWindow 中的用戶不活動? 到目前為止,我的想法是擁有一個遞增計數器的 QTimer,如果傳遞了某個值,它將鎖定應用程序。 任何鼠標或鍵交互都應將計時器設置回 0。但是我需要知道如何正確處理重置的輸入事件; 我可以重新實現:

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 嗎? 是否有更好的架構來檢測用戶活動?

您可以使用自定義事件過濾器來處理應用程序在將其傳遞給子窗口小部件之前接收的所有鍵盤和鼠標事件。

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

這肯定有效(我自己嘗試過)。

編輯:非常感謝ereOn指出我早期的解決方案不是很有用。

更好的方法之一是捕獲xidle信號,而不是從用戶捕獲這么多事件。 這里需要捕獲QEvent:MouseMove事件

最干凈的方法是覆蓋主 window 小部件的eventFilter function 並將其設置為應用程序 object 上的事件過濾器。

在過濾器中,您可以使用dynamic_cast檢查事件是否為QInputEvent 所有與用戶交互的事件都派生自QInputEvent並以這種方式被識別。

class MainWindow: public QWidget {
public:
    MainWindow() {
        QApplication::instance()->installEventFilter(this);
    }

protected:
    bool eventFilter(QObject* target, QEvent* event) override {
        if(dynamic_cast<QInputEvent*>(event)){
            // detected user interaction
        }

        return QWidget::eventFilter(target, event);
    }
};

您可以將基礎 class QWidget替換為派生自QWidget的任何 class 。 (包括QMainWindow 。)請注意, event function 必須將事件傳遞給基礎 class,並返回其返回值。

如果您有多個 window,您可能還想檢查事件目標 object 是您的 window 或其QWidget子項之一。

class MainWindow: public QWidget {
public:
    MainWindow() {
        QApplication::instance()->installEventFilter(this);
    }

protected:
    bool eventFilter(QObject* target, QEvent* event) override {
        if(dynamic_cast<QInputEvent*>(event) && (
            target == this ||
            findChildren<QWidget*>().contains(target))
        ){
            // detected user interaction
        }

        return QWidget::eventFilter(target, event);
    }
};

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM