QTreeWidget - excluding top level items from sort
<p>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.</p>

<p>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.</p>

<p>How do I achieve this?</p>

<p>The simplest solution is to create a subclass of <code>QTreeWidgetItem</code> and reimplement its <code>__lt__</code> method so that it always returns <code>False</code>. 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.</p>

<p>Here is a working demo that seems to meet your spec:</p>

<pre><code>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_())
</code></pre>

python sorting pyqt pyqt4 qtreewidget