赞
踩
简单理解:事件就是外部硬件的传入信号,如键盘按下(keyPressEvent)、鼠标点击(mousePressEvent/mousuReleaseEvent)、滑轮滚动(wheelEvent)等等。
当然,事件和信号完全是两个东西,不能混淆。
我们可以通过重写事件的虚函数去做对应事件的处理(类似于槽函数),如:
void keyPressEvent(QKeyEvent *event) override;
Qt的大多数界面类如QLineEdit、QTreeView等都有默认的事件处理方式,我们可以调用基类的函数来执行默认的事件如:
void MyLineEdit::keyPressEvent(QKeyEvent *event)
{
return QLineEdit::keyPressEvent(event);
}
一般情况下,事件会分发给获得焦点的窗口部件
,默认事件传递到这里就会结束
,不会继续传递。
焦点部件就是鼠标点击的对象,比如我们在一个QWidget里面添加一个QLineEdit,点击这个lineEdit的时候,焦点就在lineEdit部件内。
但如果我们在该部件的类中重写了事件处理函数,忽略(ignore)了这个事件,那么这个事件就会传递给这个部件的父部件(注意父部件和父类不是一个东西:父部件是父对象,qt特有的;父类是超类,c++的)。
文档原文:
void QEvent::ignore()
Clears the accept flag parameter of the event object, the equivalent of calling setAccepted(false).
Clearing the accept parameter indicates that the event receiver does not want the event.Unwanted events might be propagated to the parent widget.
See also accept().
void MyLineEdit::keyPressEvent(QKeyEvent *event)
{
event->ignore();
}
忽略事件之后,父部件就可以接收到这个事件了。
但是从代码很容易看出,这个部件应该不能正确执行这个事件的默认操作了(毕竟被忽略了)。
所以为了子部件也可以正常执行,也可以这样写:
void MyLineEdit::keyPressEvent(QKeyEvent *event)
{
QLineEdit::keyPressEvent(event);
event->ignore();
}
那么,什么情况下需要把事件传递给父部件呢?
这个就看具体需求了。
可能是需要对特定事件做特殊处理的情况。比如我写了一个表格窗口,view可以接收到中文输入法事件(inputMethodEvent),但是我希望接收到中文输入法事件时做特殊的处理,就需要获取这个事件。
大多数情况,我们都是直接使用Qt的类,重写事件过于麻烦,但是又想获取这个事件,要怎么办呢?
这时候就可以使用事件过滤器。
我们先来看一下事件分发机制:
QApplication事件循环响应事件→焦点部件接收到事件先调用event()函数做事件分发,即根据事件的类型调用不同的事件处理函数如:mouseEvent、keyPressEvent、TimerEvent(函数名不是全称)
所以顺序就是app→event→子事件
其中,事件过滤器在app→event之间,也就是说,在事件还没有到达事件分发器之前就会被截胡,之后怎么处理就是我们说的算了。这时我们需要考虑两个问题:
我们需要给要截胡的对象下载一个过滤器,只要他们下载了这个过滤器,我们就满足截胡的先行条件了:
lineEdit->installEventFilter(widget);
// lineEdit是被截胡的对象,widget是截信号的对象,一般可以直接用this。
当我们给截胡对象下载完过滤器之后,就可以开始截事件做处理了。
bool eventFilter(QObject *obj, QEvent *e)
{
if (obj == lineEdit) {
if (e->type() == QEvent::InputMethod) // inputMethod 就是输入法事件
qDebug() << "filter"; // 这里可以写处理代码
}
return QWidget::eventFilter(obj,e); // 不影响默认事件过滤
}
函数解释:
文档说明
In your reimplementation of this function, if you want to filter the event out, i.e. stop it being handled further, return true; otherwise return false.
在重新实现此函数时,如果您想过滤掉事件,即停止进一步处理,请返回true;否则返回false。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。