为什么它在功能(d->eventFilters.prepend(obj)
)中使用QObject::installEventFilter
而不是append(obj),我想知道为什么以这种方式设计它。我对此很好奇。
void QObject::installEventFilter(QObject *obj)
{
Q_D(QObject);
if (!obj)
return;
if (d->threadData != obj->d_func()->threadData) {
qWarning("QObject::installEventFilter(): Cannot filter events for objects in a different thread.");
return;
}
// clean up unused items in the list
d->eventFilters.removeAll((QObject*)0);
d->eventFilters.removeAll(obj);
d->eventFilters.prepend(obj);
}
答案 0 :(得分:0)
之所以这样做,是因为首先要处理最近安装的事件过滤器,即它必须位于过滤器列表的开头。通过从begin()
到end()
依次遍历列表来调用过滤器。
首先要处理最近安装的过滤器,因为只有两个简单的选择是首先处理还是最后处理。第二种选择没有用:过滤事件时,您想先决定发生什么事情。好吧,但是随后会有一些新用户的过滤器出现在您的过滤器之前,那又如何呢?如下所示:事件过滤器用于修改功能-已经存在的功能。如果在现有功能内的某处添加了过滤器,则可以有效地连接到行为不明的部分定义的系统。毕竟,即使Qt的实现也使用事件过滤器。它们提供了记录的行为。通过最后插入事件过滤器,您根本无法确定会看到什么事件-这完全取决于过滤器上方每层功能的实现细节。
安装了事件过滤器的系统就像洋葱上的一层皮肤-该系统的用户只能看到皮肤,而不是里面的东西,而不是实现。但是,如果愿意,他们可以在顶部添加自己的皮肤,并以此方式实现新功能。他们不能挖洋葱,因为他们不知道里面有什么。当然,这是一个概括:他们不知道,因为它没有形成API,它们之间的契约以及系统的实现。他们可以自由阅读源代码和/或对系统进行反向工程,然后将事件过滤器插入所需列表中的任何位置。毕竟,一旦您可以访问QObjectPrivate
,就可以根据需要修改事件过滤器列表。但是,您不仅要对在公共API上添加的内容负责,而且还要对许多基础层的行为负责-并且责任扩大了。更新该工具包几乎是不可能的,因为您必须审核代码和/或验证测试范围,以确保内部组件中的某些内容不会损坏。