Qt是一种“事件驱动”的框架,其通信核心就是eventLoop事件循环。
其他的东西不多言,这里提一下其中一个比较特殊的东西——事件过滤器的一些思考。
事件过滤器的函数原型为:
[virtual] bool QObject::eventFilter(QObject *watched, QEvent *event)
- 虚函数:意味着可以override,可以定制自己需要的事件过滤器。
- bool:return type为bool类型,表示该事件是否被成功过滤。true表示过滤成功,不再继续往下分发;false表示过滤失败,需要继续往下分发。
- 参数:QObject表示此时正在过滤的对象,QEvent表示此时正在过滤的事件。
其中,以前忽略的一点就是其返回类型。
在以往写事件过滤器的时候,都是跟随者以往的一些示例写的,返回值可以说都是模仿其写的,根本就是不知其所以然。
在今天,知道了这点之后就可以发现以前在写这部分内容的时候忽略的点了。
比如说,以前只知道在事件被捕获之后,需要调用其基类的事件过滤器函数,不然可能会造成控件不可见的情况。
不过一直是处于会出现这种问题,但是不清楚问题出现的本质原因的情况。
今天可以说是知道了这个原因,因为在事件过滤器正常捕获控件之后,返回值是true,表示该事件已经被捕获,不再继续往下分发。
但是如果处理的东西不是该控件的该事件,会造成事件在这里就中断了,所以需要调用其基类的事件过滤器,将此事件传递过去。
手册中的说法是:
pass the event on to the parent class.
算了,给个手册中的示例吧:
class MainWindow : public QMainWindow
{
public:
MainWindow();
protected:
bool eventFilter(QObject *obj, QEvent *ev);
private:
QTextEdit *textEdit;
};
MainWindow::MainWindow()
{
textEdit = new QTextEdit;
setCentralWidget(textEdit);
textEdit->installEventFilter(this);
}
bool MainWindow::eventFilter(QObject *obj, QEvent *event)
{
if (obj == textEdit) {
if (event->type() == QEvent::KeyPress) {
QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
qDebug() << "Ate key press" << keyEvent->key();
return true;
} else {
return false;
}
} else {
// pass the event on to the parent class
return QMainWindow::eventFilter(obj, event);
}
}
由上面的示例可见,在捕获的控件不是需要的控件的时候,需要将事件丢给其基类,用于它去绘制。