有时候,对象需要查看、甚至要拦截发送到另外对象的事件。例如,对话框可能想要拦截按键事件,不让别的组件接收到;或者要修改回车键的默认处理。
Qt 提供了另外一种机制来达到这一目的:事件过滤器。
QObject有一个eventFilter()函数,用于建立事件过滤器。这个函数的签名如下:
virtual boolQObject::eventFilter(QObject *watched,QEvent *event);
事件过滤器,可以理解成一种过滤代码。事件过滤器它会检查接收到的事件。如果这个事件是我们感兴趣的类型,就进行我们自己的处理;如果不是,就继续转发。这个函数返回一个 bool 类型,如果你想将参数 event 过滤出来,比如,不想让它继续转发,就返回 true,否则返回 false。
我们来看一段简单的代码:
点击(此处)折叠或打开
-
class MainWindow : public QMainWindow
-
{
-
public:
-
MainWindow();
-
protected:
-
bool eventFilter(QObject *obj, QEvent *event);
-
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);
-
}
- }
安装过滤器需要调用QObject::installEventFilter()函数。经存在的过滤器则可以通过QObject::removeEventFilter()函数移除。
我们重写了它的eventFilter()函数。为了过滤特定组件上的事件,首先需要判断这个对象是不是我们感兴趣的组件,然后判断这个事件的类型。在上面的代码中,我们不想让textEdit组件处理键盘按下的事件。所以,首先我们找到这个组件,如果这个事件是键盘事件,则直接返回 true,也就是过滤掉了这个事件,其他事件还是要继续处理,所以返回 false。对于其它的组件,我们并不保证是不是还有过滤器,于是最保险的办法是调用父类的函数。
返回目录:Qt学习整理