简体   繁体   English

如何优化PyQt QSortFilterProxyModel过滤器的重新实现?

[英]How to optimize PyQt QSortFilterProxyModel filter reimplementation?

I have a reimplemented QSortFilterProxyModel acceptRows to achieve custom behavior, i want it to not filter out items which have a valid child. 我有一个重新实现的QSortFilterProxyModel acceptRows以实现自定义行为,我希望它不过滤掉具有有效子代的项目。

class KSortFilterProxyModel(QSortFilterProxyModel):
    #FIXME: Funciona pero es endemoniadamente lento
    def __init__(self, parent=None):
        super(KSortFilterProxyModel, self).__init__(parent)
        self.__showAllChildren = False

    def showAllChildren(self):
        return self.__showAllChildren;

    def setShowAllChildren(self, showAllChildren):
        if showAllChildren == self.__showAllChildren:
            return
        self.__showAllChildren = showAllChildren
        self.invalidateFilter()

    def filterAcceptsRow (self, source_row, source_parent ):
        if self.filterRegExp() == "" :
            return True #Shortcut for common case

        if  super(KSortFilterProxyModel, self).filterAcceptsRow( source_row, source_parent) :
            return True

        #one of our children might be accepted, so accept this row if one of our children are accepted.
        source_index = self.sourceModel().index(source_row, 0, source_parent)
        for i in range( self.sourceModel().rowCount(source_index)):
            if self.filterAcceptsRow(i, source_index):
                return True

        return False

However this aproach doesn't seems to be efficient because with 300 items it takes almost 3 seconds to update the view, i want to know if theres a better way of doing it. 但是,这种方法似乎效率不高,因为要处理300个项目,几乎需要3秒钟来更新视图,我想知道是否有更好的方法。

PD: This class is basically a translation of a KSysGuard one i found in KDE websvn PD:此类基本上是我在KDE websvn中找到的KSysGuard的翻译。

I don't see anything obviously wrong with what you're doing. 我看不到您所做的任何明显错误。 Keep in mind that filterAcceptsRow is called for every item in your model, and this is of course going to be sluggish because the overhead of calling a Python function from C++ is a few milliseconds. 请记住, filterAcceptsRow中的每个项目都会调用filterAcceptsRow ,这当然会很缓慢,因为从C ++调用Python函数的开销只有几毫秒。 This adds up rather quickly if you have a model with a few hundred items. 如果您有一个包含数百个项目的模型,那么这将相当快地加起来。 Add to this the amount of C++ functions called from Python, and you can easily end up with the 3 seconds you're noticing. 再加上从Python调用的大量C ++函数,您会很容易地注意到3秒钟。

Also, QTableView and QSortFilterProxyModel do an awful lot of clever things to keep the signals they emit and the amount of updates required to a minimum. 而且, QTableViewQSortFilterProxyModel做了很多聪明的事情,以使它们发出的信号和所需的更新量保持在最低水平。 Sadly, this leads to very bad performance if the rows that are removed or added after a filter reset are very much scattered over your model. 令人遗憾的是,如果在重置过滤器后删除或添加的行分散在模型上,则会导致非常糟糕的性能。

In our projects, we have made the decision to implement most of these item-based models in C++, at least for those methods that are called for every item in a model that contains more than a trivial amount of rows or columns. 在我们的项目中,我们决定在C ++中实现大多数此类基于项目的模型,至少是针对包含多于少量行或列的模型中的每个项目调用的那些方法。 However, this may not be the answer you're looking for, especially if your update delays are caused by eg other signal handlers connected to the same model. 但是,这可能不是您要寻找的答案,尤其是如果您的更新延迟是由例如连接到同一模型的其他信号处理程序引起的。 Emitting a signal is usually the same as calling a method. 发出信号通常与调用方法相同。

In short, you'd best use a profiler to see where your application is spending most of its time, and use C++ if it is in these methods that are called once (or even more than once) per item in your model. 简而言之,最好使用探查器来查看应用程序大部分时间在哪里使用,如果在这些方法中对模型中的每个项目调用一次(甚至多次调用),则使用C ++。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM