繁体   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