为什么在函数(QObject :: installEventFilter)中使用d-> eventFilters.prepend(obj)而不是append(obj)

时间:2018-07-02 02:01:28

标签: qt

为什么它在功能(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);
}

1 个答案:

答案 0 :(得分:0)

之所以这样做,是因为首先要处理最近安装的事件过滤器,即它必须位于过滤器列表的开头。通过从begin()end()依次遍历列表来调用过滤器。

首先要处理最近安装的过滤器,因为只有两个简单的选择是首先处理还是最后处理。第二种选择没有用:过滤事件时,您想先决定发生什么事情。好吧,但是随后会有一些新用户的过滤器出现在您的过滤器之前,那又如何呢?如下所示:事件过滤器用于修改功能-已经存在的功能。如果在现有功能内的某处添加了过滤器,则可以有效地连接到行为不明的部分定义的系统。毕竟,即使Qt的实现也使用事件过滤器。它们提供了记录的行为。通过最后插入事件过滤器,您根本无法确定会看到什么事件-这完全取决于过滤器上方每层功能的实现细节。

安装了事件过滤器的系统就像洋葱上的一层皮肤-该系统的用户只能看到皮肤,而不是里面的东西,而不是实现。但是,如果愿意,他们可以在顶部添加自己的皮肤,并以此方式实现新功能。他们不能挖洋葱,因为他们不知道里面有什么。当然,这是一个概括:他们不知道,因为它没有形成API,它们之间的契约以及系统的实现。他们可以自由阅读源代码和/或对系统进行反向工程,然后将事件过滤器插入所需列表中的任何位置。毕竟,一旦您可以访问QObjectPrivate,就可以根据需要修改事件过滤器列表。但是,您不仅要对在公共API上添加的内容负责,而且还要对许多基础层的行为负责-并且责任扩大了。更新该工具包几乎是不可能的,因为您必须审核代码和/或验证测试范围,以确保内部组件中的某些内容不会损坏。