Вы можете сделать свою собственную сортировку без необходимости пополнять дерево. Вам просто нужно перегрузить оператор элемента '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 (), чтобы вернуть ваше значение таким, каким оно было.