Наиболее эффективный выбор модели PyQt в больших деревьях

В настоящее время я выбираю несколько строк в дереве модели с кодом ниже. Но это может быть очень медленным в больших сессиях с большим количеством узлов. Я подозреваю, что это не очень эффективно, поскольку, вероятно, он выбирает строки одну за другой. Есть ли что-нибудь, что может ускорить процесс - например, не обновлять при выборе до последнего или выбирать все за один вызов?

selectionModel = self.tree.selectionModel()
selectionModel.clear()

for node, i in self.tree.model().iterNodeAndIndexs():
    if nodeCondition:
        selectionModel.select(i, selectionModel.Select | selectionModel.Rows)

person mtmt    schedule 18.05.2015    source источник


Ответы (1)


Как описано в Руководстве по программированию модели/представления. вы можете поместить верхний левый и нижний правый индексы в QItemSelection и выбрать сразу все ячейки.

Обратите внимание, что для иерархических моделей вам придется делать выборку на всех уровнях дерева рекурсивно (см. выбор раздела всех примечаний). Что-то вроде этого:

def mySelectRows(treeView, parentIndex=None, topRow=0, bottomRow=None):

    if parentIndex is None:
        parentIndex = QtCore.QModelIndex()

    model = treeView.model()
    totalSelection = QtGui.QItemSelection()

    def populateSelection(parentIndex, topRow=0, bottomRow=None):

        if bottomRow is None:
            bottomRow = model.rowCount(parentIndex)

        leftCol, rightCol = 0, model.columnCount(parentIndex)

        topLeft = model.index(topRow, leftCol, parentIndex)
        bottomRight = model.index(bottomRow-1, rightCol-1, parentIndex)
        newSelection = QtGui.QItemSelection(topLeft, bottomRight)
        totalSelection.merge(newSelection, QtGui.QItemSelectionModel.Select)

        for row in range(topRow, bottomRow):
            childIndex = model.index(row, 0, parentIndex)
            if model.rowCount(childIndex) > 0:
                populateSelection(childIndex)

    # Start recursion
    populateSelection(parentIndex, topRow=topRow, bottomRow=bottomRow)
    selectionModel = treeView.selectionModel()
    selectionModel.select(totalSelection, 
                          QtGui.QItemSelectionModel.ClearAndSelect)

В зависимости от вашей реализации модели может быть быстрее заменить if model.rowCount(childIndex) > 0 на if model.hasChildren(childIndex)

person titusjan    schedule 18.05.2015
comment
Вы можете использовать QItemSelection.merge(), чтобы объединить несколько вариантов вместе. Позволяет ли это вам избежать рекурсии и, таким образом, избежать повторных вызовов selectionModel.select()? - person three_pineapples; 19.05.2015
comment
@three_pineapples. Нет, вам все еще нужна рекурсия (как указано в документации), иначе будут выбраны только элементы верхнего уровня. Тем не менее, это улучшение, поскольку множественные вызовы selectionModel.select(), вероятно, делают его медленным (и вызывают повторную подачу сигнала selectionModel.selectionChanged). Я обновил свой код, чтобы использовать selectionModel.select(). Спасибо. - person titusjan; 19.05.2015