Qt中的事件过滤器
问题:有时候我们在自定义事件时,并不是需要所有的事件类型都可以触发的,例如在数字键盘中,我们就不希望按下字母可以触发事件并输入到编辑框中。那么Qt有什么机制可以过滤掉一部分事件呢?
Qt中的事件过滤器
- 事件过滤器可以对其他组件接收到的事件进行监控
- 任意的QObject对象都可以作为事件过滤器使用
- 事件过滤器对象需要重启eventFilter() 函数
- 组件通过installEventFilter() 函数安装事件过滤器
- 事件过滤器在组件之前接收到事件
- 事件过滤器能够决定是否将事件转发到组件对象
###事件过滤器的典型实现
示例代码:事件过滤器的使用
//MyLineEdit.h
class MyLineEdit : public QLineEdit
{
Q_OBJECT
public:
explicit MyLineEdit(QWidget *parent = 0);
bool event(QEvent* e);
void keyPressEvent(QKeyEvent* e);
signals:
public slots:
};
//MyLineEdit.cpp
MyLineEdit::MyLineEdit(QWidget *parent) :
QLineEdit(parent)
{
}
bool MyLineEdit::event(QEvent* e)
{
if( e->type() == QEvent::KeyPress )
{
qDebug() << "MyLineEdit::event";
}
return QLineEdit::event(e);
}
void MyLineEdit::keyPressEvent(QKeyEvent* e)
{
qDebug() << "MyLineEdit::keyPressEvent";
QLineEdit::keyPressEvent(e);
//e->ignore(); //当注释以后,事件不会继续传给父组件了
}
//Widget.h
class Widget : public QWidget
{
Q_OBJECT
MyLineEdit myLineEdit;
public:
Widget(QWidget* parent = 0);
bool event(QEvent* e);
void keyPressEvent(QKeyEvent* e);
bool eventFilter(QObject* obj, QEvent* e);
~Widget();
};
//Widget.cpp
Widget::Widget(QWidget *parent)
: QWidget(parent), myLineEdit(this)
{
myLineEdit.installEventFilter(this); //使用事件过滤器前必须先安装
}
bool Widget::event(QEvent* e)
{
if( e->type() == QEvent::KeyPress )
{
qDebug() << "Widget::event";
}
return QWidget::event(e);
}
void Widget::keyPressEvent(QKeyEvent* e)
{
qDebug() << "Widget::keyPressEvent";
QWidget::keyPressEvent(e);
}
bool Widget::eventFilter(QObject* obj, QEvent* e)
{
bool ret = true;
if( (obj == &myLineEdit) && (e->type() == QEvent::KeyPress) )
{
qDebug() << "Widget::eventFilter";
QKeyEvent* evt = dynamic_cast<QKeyEvent*>(e);
switch(evt->key())
{
case Qt::Key_0:
case Qt::Key_1:
case Qt::Key_2:
case Qt::Key_3:
case Qt::Key_4:
case Qt::Key_5:
case Qt::Key_6:
case Qt::Key_7:
case Qt::Key_8:
case Qt::Key_9:
ret = false; //返回false表明以上事件过滤失败
break;
default:
break;
}
}
else
{
ret = QWidget::eventFilter(obj, e); //调用父类事件过滤器
}
return ret;
}
现象:
- 当键盘输入字母时,文本框无显示,命令行仅打印出:
Widget::eventFilter- 当键盘输入数字时,文本框显示对应数字,命令行打印出:
Widget::eventFilter
MyLineEdit::event
MyLineEdit::keyPressEvent