installEventFilter函数如下:
void QObject::installEventFilter(QObject *filterObj)
Qt助手的解释如下:
在对象上安装一个事件过滤器filterObj。如下:
monitoredObj->installEventFilter(filterObj);
其中monitoredObj、filterObj都是QObject的子类。上面代码意思是:在monitoredObj对象上安装一个事件过滤器filterObj。
传给monitoredObj的事件先经过filterObj的eventFilter处理后再由monitorObj处理
该函数一般和如下函数配合使用:
[virtual] bool QObject::eventFilter(QObject *watched, QEvent *event)
注意:该函数是虚函数,也就是说派生自QObject的子类可以重写该函数。
上面monitoredObj对象安装一个filterObj过滤器后,则可以在filterObj对象所在类的eventFilter函数中拦截发送到monitoredObj对象的事件。如下为KeyPressEater类:
class KeyPressEater : public QObject
{
Q_OBJECT
...
protected:
bool eventFilter(QObject *obj, QEvent *event) override;
};
bool KeyPressEater::eventFilter(QObject *obj, QEvent *event)
{
if (event->type() == QEvent::KeyPress) {
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
qDebug("Ate key press %d", keyEvent->key());
return true;
} else {
// standard event processing
return QObject::eventFilter(obj, event);
}
}
现在我们在按钮或QListView两个窗体部件上安装过滤器,如下:
KeyPressEater *keyPressEater = new KeyPressEater(this);
QPushButton *pushButton = new QPushButton(this);
QListView *listView = new QListView(this);
pushButton->installEventFilter(keyPressEater);
listView->installEventFilter(keyPressEater);
此时如果在按钮或QListView获取到键盘焦点时按下Esc键,按键事件被 KeyPressEater类的eventFilter函数拦截,从而弹出:
Ate key press 1048576
其中1048576为Esc键的虚拟键码。Qt的QShortcut类就是采取这种技术实现的。
注意:
- 事件过滤器对象filterObj能阻止(拦截)或放行发向对象monitoredObj的事件。
- 事件过滤器对象filterObj通过其类的eventFilter函数来接收事件。
- 如果过滤器对象filterObj所在类的eventFilter函数返回true,则该事件被拦截,也就是原本发向monitoredObj对象的事件不再发向monitoredObj对象;如果过滤器对象filterObj所在类的eventFilter函数返回false,则不拦截该事件,事件依然发向monitoredObj对象。
- 如果同一个对象上安装多个过滤器,则最后一个过滤器首先被激活调用。
- 如果在eventFilter函数中删除了接收事件的对象,请确保eventFilter函数返回true,否则Qt将会发送事件到删除的接收对象上,这将导致程序崩溃。
- monitoredObj对象和filterObj对象必须位于同一个线程中。如果filterObj对象在不同的线程,调用installEventFilter函数则Qt什么都不会做。
- 如果调用installEventFilter函数后,monitoredObj对象和filterObj对象被移到不同的线程中去了,则eventFilter函数不会被调用,直到monitoredObj对象和filterObj对象回到同一线程时才会被调用。
- 过滤器对象filterObj所在类的eventFilter函数的第一个参数是被拦截对象monitoredObj,即installEventFilter函数的调用者。以上面的 KeyPressEater例子来说, KeyPressEater类的eventFilter函数的第一个参数是pushButton或listView
原文链接:https://blog.csdn.net/danshiming/article/details/122792144