事件处理介绍
- 系统平台会将由系统或者Qt自身产生的消息转换成Qt事件,比如鼠标移动按下,键盘按下弹起等都会被系统捕捉到然后变成Qt事件
- Qt事件是QEvent对象的子类
- Qt事件用来描述内部或者外部发生的动作
- 事件可以由QObject子类的任何实例接收和处理,但主要与QWidget相关
事件处理方式顺序
- Qt事件产生后立即被分发到QWidget对象
- QWidget中的event(QEvent *)进行事件处理
- event()函数本身并不会处理事件,而是根据事件的类型,调用其它特定的事件函数来处理
事件过滤器
- 事件过滤器是一个对象
- 事件过滤器可以对接受到的事件进行过滤和监控
- 事件过滤器的实现需要调用installEventFilter()来安装
- 事件过滤器的实现需要重写eventFilter()函数
- 事件过滤器能够决定是否将事件传递给组件对象。
一个事件有两个信息:谁的事件和什么事件。
在不使用事件过滤器的情况下,应用程序会直接将事件发送给对应的控件对象,由对应的控件对象自己去处理,但是如果使用了事件过滤器,应用程序会将控件的事件首先发给事件过滤器,但这前提是那个控件安装了事件过滤器,这样应用程序才知道它需要被监控,才会把它的事件先发送给事件过滤器,事件过滤器在eventFilter()中对事件进行处理分发并给控件对象。
当子对象的事件发生了,首先是发送给父对象的eventFilter()函数,然后由父对象的eventFilter()函数处理完之后再分发给各个子对象的event函数。
事件过滤器用法演示
安装过滤器
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
btn = new QPushButton;
btn->setText("test");
QHBoxLayout *hLayout = new QHBoxLayout;
hLayout->addWidget(btn);
setLayout(hLayout);
btn->installEventFilter(this);
connect(btn, &QPushButton::pressed, this, [=](){
qDebug() << "xxx";
});
}
实现eventFilter
bool Widget::eventFilter(QObject *object, QEvent *event)
{
//监视按钮按下动作
if (object == btn && event->type() == QEvent::MouseButtonPress) {
qDebug() << "x";
return true;
}
return false;
}
当btn按钮按下时,pressed信号首先会被送到eventFilter中,经过处理后再决定是否分发到btn。在这里,只会打印出"x",而不是"xxx"。