概述
事件传递过程
在子组件中将事件进行处理后可能再将事件传递给父组件对象。
QEvent类是所有事件处理的父类
QEvent中的关键成员函数
–void ignore();
接收者忽略当前事件,但事件可能传递给父组件
–void accept();
接收者期望处理当前事件
–bool isAccept();
判断当前事件是否被处理
示例:事件处理的顺序
先构建一个自定义的MyLineEdit类,在类里重写event()和keyPressEvent()
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作为父组件,当子组件忽略事件处理时将会将事件传递到父组件进行处理。
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效果。
- 事件过滤器特点:
- 事件过滤器使用套路:判断某个对象,判断某种事件类型,调用默认处理函数。
示例:事件过滤
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--事件传递过程和事件过滤器所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复