Qtreewidget inserttoplevelitem - Индекс, указанный не точно, в дереве?
-
22-09-2019 - |
Вопрос
Я не могу должным образом вставить 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_()