I have a 2-level QTreeWidget. The top level only has one column and is just used for grouping the second level, which holds the actual multi-column data.
When I sort by clicking on a header (or any other way, really), I only want the second level to be sorted, as the top-level items have a fixed order set elsewhere in the app and shouldn't be affected.
How do I achieve this?
The simplest solution is to create a subclass of QTreeWidgetItem
and reimplement its __lt__
method so that it always returns False
. Qt uses a stable sort algorithm, so this means the items will always retain their original order. This subclass should be used for the top-level items only.
Here is a working demo that seems to meet your spec:
import sys
from random import randint
from PyQt4 import QtCore, QtGui
class TreeWidgetItem(QtGui.QTreeWidgetItem):
def __lt__(self, other):
return False
class Window(QtGui.QTreeWidget):
def __init__(self):
super(Window, self).__init__()
self.setHeaderLabels('Name X Y'.split())
for text in 'One Two Three Four'.split():
parent = TreeWidgetItem([text])
for text in 'Red Blue Green Yellow'.split():
child = QtGui.QTreeWidgetItem([
text, str(randint(0, 9)), str(randint(0, 9))])
parent.addChild(child)
self.addTopLevelItem(parent)
self.expandAll()
self.setSortingEnabled(True)
self.sortByColumn(0, QtCore.Qt.AscendingOrder)
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
window = Window()
window.setGeometry(800, 100, 320, 400)
window.show()
sys.exit(app.exec_())