背景:Qt应用运行时,键盘ESC按下导致程序异常退出,需要在程序整个运行期间拦截ESC这个按键响应。
Qt整个运行机制是事件循环,在运行期间如果需要拦截特定的任务,Qt提供一个便捷的处理机制,就是事件过滤器。因为过滤器的定义在QObject类中,所以只要继承了这个类,就可以使用installEventFilter()这个方法来使能过滤器。当然默认的过滤器不会过滤任何行为,如果想过滤特定行为,则需要对过滤器进行重写。
QObject类中定义的eventfilter():
virtual bool QObject::eventFilter ( QObject * watched, QEvent * event );
此方法返回bool,过滤就返回true,否则flase。
重写事件过滤器:
#include <QKeyEvent>
class MyEventFilter : public QObject {
public:
bool eventFilter( QObject *obj, QEvent *event ) override {
if ( event->type() == QEvent::KeyPress ||
event->type() == QEvent::KeyRelease ) {
if ( ( (QKeyEvent *) event )->key() == Qt::Key_Escape ) {
qDebug("ESC press!");
return true;
}
}
return false;
}
};
完成对事件过滤器的重写后,需要在需要拦截的页面进行安装,如果是在子页面(子进程)中进行安装,那么它只在当前页面生效,并不会影响到别的页面,如果想在全局使用,那么就需要在第一个基页面中安装。安装是调用QObject类中的一个方法。
QObject类中定义的安装方法:
void QObject::installEventFilter ( QObject * filterObj )
全局过滤这个键盘事件:
QApplication a(argc, argv);
a.installEventFilter(new MyEventFilter);
最终效果:
Qt应用启动期间,不会响应按压ESC键,程序不会退出,完成了最初目的,类似操作可以拦截更多事件。