我是靠谱客的博主 威武爆米花,这篇文章主要介绍Qt学习之路27--事件传递过程和事件过滤器,现在分享给大家,希望可以做个参考。

事件传递过程

这里写图片描述
在子组件中将事件进行处理后可能再将事件传递给父组件对象。
QEvent类是所有事件处理的父类

QEvent中的关键成员函数

–void ignore();
接收者忽略当前事件,但事件可能传递给父组件
–void accept();
接收者期望处理当前事件
–bool isAccept();
判断当前事件是否被处理

示例:事件处理的顺序

先构建一个自定义的MyLineEdit类,在类里重写event()和keyPressEvent()

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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作为父组件,当子组件忽略事件处理时将会将事件传递到父组件进行处理。

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Widget::Widget(QWidget *parent): QWidget(parent), LineEdit(this)//LineEdit设置父组件 { } 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); }

重写事件处理函数后,由系统发送来的系统消息就会由重写后的event函数处理,然后根据事件类型调用相应的事件处理函数。
当事件类型是按下键盘时触发调用MyLineEdit::keyPressEvent函数,由于调用了ignore()函数,它就会告诉应用程序当前事件没有被处理,所以就会传递给父组件去处理。
这里写图片描述
在执行了子组件(MyLineEdit对象)的事件处理函数时后又执行了父组件(Widget对象)的事件处理函数。

注意:如果我们希望父组件对象或其他来接着处理当前的事件,那么一定要调用ignore()函数。

事件过滤器

  • 事件过滤器可以对其他组件接收到的事件进行监控。
  • 任意的QObject对象都可以作为事件过滤器使用,QWidget对象也是一个QObject对象。
  • 事件过滤器需要重写eventFilter()函数。
  • 监控的意义在于可以将事件没收,用来定制一些有用的GUI效果。
  • 事件过滤器特点:
    这里写图片描述
  • 事件过滤器使用套路:判断某个对象,判断某种事件类型,调用默认处理函数。
    这里写图片描述

示例:事件过滤

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
Widget::Widget(QWidget *parent): QWidget(parent), LineEdit(this) { LineEdit.installEventFilter(this);//安装事件过滤器 } bool Widget::eventFilter(QObject* obj, QEvent* e) { bool ret = true; if( (obj == &LineEdit) && (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; break; default: break; } } else { ret = QWidget::eventFilter(obj, e); } return ret; }

结果返回true表示事件已经被处理,不需要传递给obj对象(其中obj表示已经安装了事件过滤器的组件对象);返回false时需要传递到obj对象去进行处理。
只有按下的是数字,事件才会被传递给安装了事件过滤器的组件对象。

这里写图片描述

注意:
1、在使用事件过滤器之前一定要先安装过滤器到想要关注的组件对象。
2、只有当按下的是数字才会将事件发送到组件对象(当eventFilter返回false时发送事件到组件对象)。否则会将其没收,不会进行事件处理,如后三行的打印语句,并不包括事件处理函数里的打印语句,表明并没有进行事件处理。

小结

  • Qt应用程序有严格的事件处理顺序
  • Qt事件可能在处理后传递给父组件对象
  • 可以通过installEventFilter()函数安装事件管理器
  • 事件管理器可以对其它组件接收到的事件进行监控
  • 事件过滤器能决定是否将事件转发到组件对象

最后

以上就是威武爆米花最近收集整理的关于Qt学习之路27--事件传递过程和事件过滤器的全部内容,更多相关Qt学习之路27--事件传递过程和事件过滤器内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(62)

评论列表共有 0 条评论

立即
投稿
返回
顶部