代码之家  ›  专栏  ›  技术社区  ›  armonge

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

  •  2
  • armonge  · 技术社区  · 14 年前

    我有一个重新实现的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
    

    但是这个方法似乎效率不高,因为有300个项目更新视图几乎需要3秒钟,我想知道是否有更好的方法。

    PD:这个类基本上是我在一个KSysGuard中找到的一个的翻译 KDE websvn

    1 回复  |  直到 8 年前
        1
  •  1
  •   Ivo    14 年前

    filterAcceptsRow 是需要的 每一项 在你的模型中,这当然是迟钝的,因为从C++调用Python函数的开销是几毫秒。如果您有一个包含几百个项目的模型,那么这会很快增加。再加上从Python调用的C++函数的数量,你很容易在你注意到的3秒内结束。

    也, QTableView QSortFilterProxyModel 做很多聪明的事情来保持他们发出的信号和所需的更新量最小化。遗憾的是,如果在过滤器重置后删除或添加的行非常分散地分布在模型中,这将导致非常糟糕的性能。

    简而言之,你最好使用一个剖析器来查看你的应用程序大部分时间在哪里,如果这些模型中的每一个项目被调用一次(甚至不止一次),那么使用C++。