如何在Qt GUI应用程序内部检测应用是否处于空闲状态?

8
如何检测GUI应用程序已经空闲(即没有用户交互)一段时间?我有n个Qt屏幕,当应用程序空闲5秒钟时,我想要显示日期时间屏幕,并且当我点击日期时间屏幕时,它应该返回到上一个屏幕。目前我正在使用以下代码,现在如何检查系统是否空闲5秒钟并带来一个新的窗体,当有人鼠标移动/点击它应该返回到上一个窗体。
CustomEventFilter::CustomEventFilter(QObject *parent) :
    QObject(parent)
{   
    m_timer.setInterval(5000);
    connect(&m_timer,SIGNAL(timeout()),this,SLOT(ResetTimer()));
}

bool CustomEventFilter::eventFilter(QObject *obj, QEvent *ev)
{
    if(ev->type() == QEvent::KeyPress ||
           ev->type() == QEvent::MouseMove)
    {
        ResetTimer();
        return QObject::eventFilter(obj, ev);

     }
    else
    {

    }
}

bool CustomEventFilter::ResetTimer()
{
    m_timer.stop(); // reset timer

}

我的main.cpp文件看起来像这样:

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainForm w;
    w.show();
    CustomEventFilter filter;
    a.installEventFilter(&filter);

    return a.exec();


}

感谢您的选择。

显示/关闭表单有什么问题? - Macke
1
你需要在提问/反馈时更具建设性,而不是仅仅说“给我代码”和“不起作用,帮帮我”。我们无法为你完成所有的工作,也没有足够聪明的头脑来弄清楚什么有效、什么无效,除非你学会如何提供更多关于问题的信息。 - Macke
@Macke:谢谢你,Macke。下次在SO上提问时我会记住的。 - Bokambo
2个回答

5

如何在鼠标/键盘事件上覆盖QCoreApplication::notify和一个定时器?

(或者只需存储事件的时间,并使定时器定期检查该值,这可能比一直重置定时器更快。)

class QMyApplication : public QApplication
{
public:
    QTimer m_timer;

    QMyApplication() {
        m_timer.setInterval(5000);
        connect(&m_timer, SIGNAL(timeout()), this, SLOT(app_idle_for_five_secs());
        m_timer.start();
    }
slots:
    bool app_idle_for_five_secs() {
        m_timer.stop();
        // ...
    }
protected:
    bool QMyApplication::notify ( QObject * receiver, QEvent * event )
    {
        if (event->type == QEvent::MouseMove || event->type == QEvent::KeyPress) {
             m_timer.stop(); // reset timer
             m_timer.start();
        }    
        return QApplicaiton::notify(receiver, event);
    }
};

@user662285:已添加。可能不是很高效或完整,但它应该能让你朝着正确的方向开始。 - Macke
@Macke:我需要编写什么代码来检测系统闲置了5秒钟,然后显示我的日期时间屏幕? - Bokambo
1
@user662285:我已经添加了一些示例代码来检测5秒钟的空闲时间。日期时间屏幕应该很简单,除非您在不同的进程中运行程序(有各种选项可用,但您需要更清楚地定义您的目标),或者不够了解Qt(通过做一些教程来解决后者)。这不是一个可以为您提供代码而不需要您思考的网站。请考虑您的问题,将其分解为可解决的子问题,攻击每个子问题并寻求详细的帮助。尽量避免“大范围”的问题。 - Macke
@Macke:我已经按照你的建议详细说明了我的代码。但是那段代码没有检测到系统闲置了5秒钟。我的要求是,当我运行我的应用程序并且5秒钟内什么都不做时,日期时间屏幕(我已经有了)应该出现。 - Bokambo
@user:你需要启动计时器(我现在已经添加了)。这不起作用吗?你尝试过调试(在事件处理程序中使用printf)来查看发生了什么吗?此外,请参阅OrcunC的评论,您需要在处理程序中停止/启动计时器,而不仅仅是停止它。启动是必要的。我只是停止/启动它以确保它从停止/启动间隔触发5秒钟。 - Macke
我不建议你覆盖QApplication,而是覆盖你的QWidget。参考这个链接:https://doc.qt.io/qt-5/qobject.html#event - antonyjr

5
根据QT Documentation
使用0超时的QTimer,使应用程序执行空闲处理(即在没有待处理事件时执行特殊功能)。可以使用processEvents()实现更高级的空闲处理方案。
因此,您需要创建一个0超时间隔的QTimer,并将其连接到在应用程序空闲时调用的插槽中。

关于你的代码:看起来你只是在ResetTimer()方法中停止了计时器,但你没有重新启动它!Macke的代码似乎是正确的,但在每个鼠标和键盘事件中停止和重新启动计时器可能非常低效!此外,在第一个空闲时间插槽调用时,他也停止了计时器,但没有重新启动它或者不关心连续的空闲事件。所以我认为他的代码也不完美。 - O.C.
@OrunC:你能帮忙吗? - Bokambo
1
@Orcunc:不,这并不完美,但我认为如果我们在这里追求完美,我们就无法取得任何进展。;) 更新最后事件时间值并运行一个5秒计时器来检查此值(并在适当的时间内重置自身,例如如果上次事件是2秒前,则为3秒)可能是在计算能力方面最有效的。 - Macke
像这样做:QTimer t; //在头文件中定义它 //在cpp文件中将其连接到您的槽 connect(t, SIGNAL(timeout()), h, SLOT(idleCallback())); t.start(0); //启动空闲处理计时器 - O.C.
@OrunC:这个流程没问题。m_timer.setInterval(5000); connect(&m_timer,SIGNAL(timeout()),this,SLOT(ResetTimer())); m_timer.start(0); 在我的重置计时器中,我应该显示我的日期时间表格吗? - Bokambo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接