在嵌入式qt项目中,有时并不需求屏幕一直亮着,需要一段时间不操作时,将屏幕背光关掉,以达到节能的目的;
在qt项目中,可以通过重写事件过滤器来实现屏幕操作的检测,加上定时器的时间控制,可以实现指定时间内没有屏幕操作,给应用程序发送一个信号;
下面是我写的一个测试代码:
首先是事件过滤器的重写代码:
这里我把这个类做成单实例的了,这样可以在应用程序中全局使用,(所有界面的类中都可以连接其超时信号)
ceventfilter.cpp
#include "ceventfilter.h" #include <QDebug> #include <QEvent> CEventFilter::CEventFilter(QObject *parent) : QObject(parent) { m_timeOutMSec = 30000; m_eventTimer = new QTimer; m_eventTimer->setInterval(m_timeOutMSec); connect(m_eventTimer, SIGNAL(timeout()), this, SLOT(onTimerTimeOut())); m_eventTimer->start(m_timeOutMSec); } CEventFilter::~CEventFilter() { delete m_eventTimer; } bool CEventFilter::eventFilter(QObject *ob, QEvent *e) { if( e->type()==QEvent::MouseMove||e->type()==QEvent::MouseButtonPress ||e->type()==QEvent::MouseButtonRelease)// 判断如果是鼠标移动事件 { if(m_eventTimer->isActive())//have_dosthtimer很显然是个定时器,在这判断是否已经开启. { m_eventTimer->stop(); m_eventTimer->start();//如果已经开启,并且有鼠标移动事件就需要计时器重新计算(这里是30s) //qDebug()<<"detect touch event, restart timer, Event type: "<<e->type(); } } return QObject::eventFilter(ob,e);//这里是把事件发送出去, } //超时发送信号 void CEventFilter::onTimerTimeOut() { qDebug()<<m_timeOutMSec<<" ms not operation ..."; emit noOperationDetect(); } //设置超时时间 void CEventFilter::setTimeOutSecond(int sec) { m_timeOutMSec = sec*1000; m_eventTimer->stop(); m_eventTimer->setInterval(m_timeOutMSec); m_eventTimer->start(); } CEventFilter *CEventFilter::m_instance = NULL; CEventFilter *CEventFilter::getInstance() { if ( m_instance == NULL ) { m_instance = new CEventFilter; } return m_instance; }
头文件:
ceventfilter.h
#ifndef CEVENTFILTER_H #define CEVENTFILTER_H #include <QObject> #include <QTimer> #define TIME_OUT_TIME 30000 class CEventFilter : public QObject { Q_OBJECT protected: explicit CEventFilter(QObject *parent = 0); ~CEventFilter(); static CEventFilter *m_instance; virtual bool eventFilter(QObject *ob, QEvent *e); //重写事件过滤器 public: static CEventFilter *getInstance(); void setTimeOutSecond(int sec); //设置超时时间 signals: void noOperationDetect(); //时间超时时发送信号 public slots: void onTimerTimeOut(); private: int m_timeOutMSec; QTimer *m_eventTimer; }; #endif // CEVENTFILTER_H
调用代码:
先在main函数里安装过滤器:
QApplication a(argc, argv); a.setFont(QFont("Microsoft Yahei", 10)); a.setWindowIcon(QIcon(":/main.ico")); a.installEventFilter(CEventFilter::getInstance()); initMasterStyleSheet();
在QWidget的构造函数中获取实例并连接信号槽:
//获取实例,连接槽函数 m_pEventFilter = CEventFilter::getInstance(); connect(m_pEventFilter, SIGNAL(noOperationDetect()), this, SLOT(onNoOperationDetect()));
这里做了一个按钮,是交替断开与连接事件过滤器超时信号的,为了测试信号的:
void MainWindow::on_pushButton_clicked() { m_pEventFilter->setTimeOutSecond(3); if(m_connectFlag) { m_connectFlag = false; qDebug()<<"diconnect signal slots"; ui->msg->setText("diconnect signal slots"); m_pEventFilter->disconnect(); } else { m_connectFlag = true; qDebug()<<"connect signal slots"; ui->msg->setText("connect signal slots"); connect(m_pEventFilter, SIGNAL(noOperationDetect()), this, SLOT(onNoOperationDetect())); } }
槽函数:
在界面上拉了一个label控件,用于显示提示信息:
void MainWindow::onNoOperationDetect() { ui->msg->setText(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss")+": non operate detect"); qDebug()<<"non operate detect"; }
这样在超时时,会在label上显示出来时间和信息:
这里我设置的是3s超时,如果鼠标不操作界面,3s会在label上更新显示信息,如果一直点界面,就不会超时;
这个如果放在嵌入式设备上运行,用手触摸屏幕也是一样的效果,和用鼠标操作是一样的;
测试代码工程已上传csdn: