2010-08-13 68 views
2

我有一个重新实现QSortFilterProxyModel acceptRows来实现自定义行为,我希望它不会筛选出有一个有效的孩子的项目。如何优化PyQt QSortFilterProxyModel过滤器重新实现?

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

我看不出有什么明显的毛病,你在做什么发现。请记住,在你的模型中,filterAcceptsRow被调用每个项目,这当然会很慢,因为从C++调用Python函数的开销只有几毫秒。如果您有一个包含几百个项目的模型,这会相当快速地加起来。再加上从Python调用的C++函数的数量,你可以很容易地结束3秒你注意到。

另外,QTableViewQSortFilterProxyModel做了很多聪明的事情,以保持它们发出的信号和所需更新的数量降到最低。可悲的是,如果在重置过滤器后删除或添加的行非常分散在您的模型上,则会导致非常差的性能。

在我们的项目中,我们决定使用C++实现大多数这些基于项目的模型,至少对于那些在模型中为每个项目调用的方法(包含的行数或列数不重要) 。但是,这可能不是您正在寻找的答案,特别是如果您的更新延迟是由其他信号处理程序连接到相同的模型。发出信号通常与调用方法相同。

简而言之,您最好使用探查器来查看您的应用程序花费了大部分时间,并且使用C++(如果这些方法在您的每个项目中被调用一次(甚至多次)模型。

+0

非常感谢,我宁愿不使用C++,但我认为这是解决这个问题的方法。 – armonge 2010-08-24 22:19:22