QTreeWidget insertTopLevelItem - индекс задан не точно отображается в дереве? - PullRequest
0 голосов
/ 26 марта 2010

Я не могу правильно вставить QTreeWidgetItem по определенному индексу, в этом случае я удаляю все QTreeWidgetItems из дерева, выполняю пользовательскую сортировку их объектов Date и затем вставляю их обратно в QTreeWidget.

Однако при вставке (даже по одной за раз) QTreeWidgetItem не вставляется в правильное место.

Код ниже распечатывается:

индекс 0: 0

индекс 0: 1 индекс 1: 0

индекс 0: 2 индекс 1: 1 индекс 2: 0

индекс 0: 3 индекс 1: 2 индекс 2: 0 индекс 3: 1

индекс 0: 4 индекс 1: 2 индекс 2: 0 индекс 3: 1 индекс 4: 3

print 'index 0: ', self.indexOfTopLevelItem(childrenList[0])

self.insertTopLevelItem(0, childrenList[1])

print 'index 0: ', self.indexOfTopLevelItem(childrenList[0]), ' index 1: ',\
    self.indexOfTopLevelItem(childrenList[1])

self.insertTopLevelItem(0, childrenList[2])

print 'index 0: ', self.indexOfTopLevelItem(childrenList[0]), ' index 1: ',\
    self.indexOfTopLevelItem(childrenList[1]), ' index 2: ', \
    self.indexOfTopLevelItem(childrenList[2])

self.insertTopLevelItem(0, childrenList[3])

print 'index 0: ', self.indexOfTopLevelItem(childrenList[0]), ' index 1: ',\
    self.indexOfTopLevelItem(childrenList[1]), ' index 2: ',\
    self.indexOfTopLevelItem(childrenList[2]), 'index 3: ',\
    self.indexOfTopLevelItem(childrenList[3])

self.insertTopLevelItem(0, childrenList[4])

print 'index 0: ', self.indexOfTopLevelItem(childrenList[0]),\
    ' index 1: ', self.indexOfTopLevelItem(childrenList[1]),\
    ' index 2: ', self.indexOfTopLevelItem(childrenList[2]),\
    'index 3: ', self.indexOfTopLevelItem(childrenList[3]),\
    'index 4: ', self.indexOfTopLevelItem(childrenList[4])

Ответы [ 2 ]

2 голосов
/ 26 марта 2010

Проблема должна быть в другом месте вашего кода. Может быть, вы не удаляете предметы должным образом? Потому что работает следующее:

import sys

from PyQt4.QtGui import *
from PyQt4.QtCore import *

app = QApplication(sys.argv)

tree = QTreeWidget()
items = [QTreeWidgetItem(['index %i' % i]) for i in range(5)]

for item in items:
    tree.insertTopLevelItem(0, item)

print 'indexes: '
for item in items:
    print tree.indexOfTopLevelItem(item),

tree.show()

app.exec_()
2 голосов
/ 26 марта 2010

Вы можете сделать свою собственную сортировку без необходимости пополнять дерево. Вам просто нужно перегрузить оператор элемента 'less'. Обратите внимание, что QT выясняет, что рисовать в ячейке, какого размера она должна быть, какой текст она должна содержать, просматривая элемент

virtual QVariant data ( int column, int role ) const

когда вы создаете элемент, вы указываете некоторую строку для конструктора, чтобы элемент отображался. Эта строка помещается в данные (.., QtCore.Qt.EditRole), поэтому эквивалентом передачи данных в конструктор является установка данных с помощью:

virtual void setData ( int column, int role, const QVariant & value)

Внутренне, данные - это просто массив, вы можете разместить все, что захотите, а его индексами являются роли (Qt.EditRole равно 2, Qt.ToolTipRole равен 3 и т. Д.), Поэтому мы просто позволяем некоторой роли содержать наши данные , скажите оператору сравнения, чтобы сравнить эти значения, и скажите setData set DisplayRole, когда мы установим, скажем, ValueRole. Вот образец:

class TreeItem(QtGui.QTreeWidgetItem):

    PythonValueRole = QtCore.Qt.UserRole

    #values are list of python objects, that have __str__ and can be compared
    def __init__(self, tree, values):
        QtGui.QTreeWidgetItem.__init__(self, tree)
        i = 0
        for v in values:
            self.setData(i, TreeItem.PythonValueRole, v)
            i += 1

    #overridden to simplify data assigning. When called with PythonValueRole, passes
    #that object's string representation to DisplayRole and EditRole
    def setData(self, col, role, value):
        if role == TreeItem.PythonValueRole:
            QtGui.QTreeWidgetItem.setData(self, col, TreeItem.PythonValueRole, value)
            # sets DisplayRole and EditRole
            QtGui.QTreeWidgetItem.setData(self, col, QtCore.Qt.EditRole, str(value)) 
            QtGui.QTreeWidgetItem.setData(self, col, QtCore.Qt.DisplayRole, str(value))
        else:
            QtGui.QTreeWidgetItem.setData(self, col, role, value)

    def __lt__(self, other):
        c = self.treeWidget().sortColumn()
        return self.data(c, TreeItem.PythonValueRole).toPyObject() < 
               other.data(c, TreeItem.PythonValueRole).toPyObject()

Я проверял, все отлично работает. Конечно, вы можете избежать наследования и переопределения lt напрямую, так как у нас была утка, мы использовали само UserRole для хранения ваших данных и установки данных, отображались напрямую с помощью setData (col, role, val) или даже удерживали только текст в роли редактирования / отображения и конвертируйте его в datetime только при сравнении, но это выглядит некрасиво. Обратите внимание, что data () содержит QVariant. Когда вы устанавливаете данные, ваш объект py автоматически конвертируется, и вам нужно вызвать toPyObject (), чтобы вернуть ваше значение таким, каким оно было.

...