Qtreewidget inserttoplevelitem - Индекс, указанный не точно, в дереве?

StackOverflow https://stackoverflow.com/questions/2520282

Вопрос

Я не могу должным образом вставить QtreeWidgetItem в определенном индексе, в данном случае я удаляю все QtreeWidgetItems из дерева, выполняя пользовательскую сортировку на их объектах даты, а затем вставляю их обратно в 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])
Это было полезно?

Решение

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

virtual QVariant data ( int column, int role ) const

Когда вы создаете элемент, вы предоставляете строку для конструктора, чтобы показать элемент. Эта строка помещена в данные (.., qtcore.qt.editrole), поэтому эквивалент передачи данных в Constuctor заключается в том, чтобы установить данные с:

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()

Я проверил, все работает нормально. Курса, вы можете избежать наследства и переопределения лейтенант напрямую, поскольку у нас была напечатающая утка, используйте сам userrole для хранения ваших данных и установленных данных, которые отображаются непосредственно с SetData (COL, роль, VAL) или даже храните только текст в роли редактирования/отображения и конвертируйте его только в DateTime во время сравнения, Но это кажется уродливым. Обратите внимание, что данные () содержит Qvariant. Когда вы устанавливаете данные, ваш объект PY автоматически преобразуется, и вам необходимо позвонить в TopyObject (), чтобы вернуть значение обратно как это.

Другие советы

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

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_()
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top