Как оптимизировать переопределение фильтра PyQt QSortFilterProxyModel? - PullRequest
2 голосов
/ 13 августа 2010

У меня есть переопределенная 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 Ответ

1 голос
/ 23 августа 2010

Я не вижу ничего явно неправильного в том, что вы делаете.Имейте в виду, что filterAcceptsRow вызывается для каждого элемента в вашей модели, и это, конечно, будет вялым, поскольку накладные расходы на вызов функции Python из C ++ составляют несколько миллисекунд.Это складывается довольно быстро, если у вас есть модель с несколькими сотнями предметов.Добавьте к этому количество функций C ++, вызываемых из Python, и вы можете легко получить 3 секунды, которые вы заметили.

Кроме того, QTableView и QSortFilterProxyModel делают очень много умных вещей длясводите сигналы, которые они излучают, и количество обновлений к минимуму.К сожалению, это приводит к очень плохой производительности, если строки, которые удаляются или добавляются после сброса фильтра, сильно разбросаны по вашей модели.

В наших проектах мы приняли решение реализовать большинство из этих элементов.основанные на C ++ модели, по крайней мере для тех методов, которые вызываются для каждого элемента в модели, который содержит более чем тривиальное количество строк или столбцов.Однако это может быть не тот ответ, который вы ищете, особенно если задержки обновления вызваны, например, другими обработчиками сигналов, подключенными к той же модели.Передача сигнала обычно аналогична вызову метода.

Короче говоря, вам лучше использовать профилировщик, чтобы увидеть, где ваше приложение проводит большую часть своего времени, и использовать C ++, если в этих методахВызываются один раз (или даже более одного раза) для каждого элемента в вашей модели.

...