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>You can use the <a href="http://doc.qt.io/qt-5/qtreewidgetitem.html#sortChildren" rel="nofollow"><code>sortChildren</code></a> method of QTreeWidgetItem(s) like this:</p>

<pre><code>sort_column = 1
# Iterate top-level elements
for index in range(tree.topLevelItemCount()):
    # Obtain the actual top-level item
    top_level_item = tree.topLevelItem(index)
    # Sort
    top_level_item.sortChildren(sort_column)
</code></pre>

<p>Notice that if you add new children to an item you need to sort it again (only the changed item)</p>

<p><strong>EDIT</strong></p>

<blockquote>
  <p>Thanks, that's a step in the right direction, but the question now is how to override the default sort behavior. I'm doing self.treeWidget.header().sortIndicatorChanged.connect(self.sââortChanged), but since that's a signal it just triggers after the widget does its regular sort, so in the end it has no effect - the top level items get sorted before the function is called</p>
</blockquote>

<p><s>Unless you go for a custom model/view, you may try two approaches (I don't have tested them):</p>

<p><strong>1. Override the "sorting" method of the <code>QTreeWidget</code></strong></p>

<p>try to replace the <code>sortItems()</code> method with some no-op, but probably the widget have other private methods that are called internally.</p>

<p><strong>2. Override the root-item <code>sortChildren()</code></strong></p>

<p>It's possible that the sorting is implemented calling the (hidden) root-item sortChildren(), that will sort the top-level-items and call the sortChildren() of those. You may be able to figure out how to get/set this item using <code>rootIndex()</code>/<code>setRootIndex()</code> and then override the sort method (e.g. <code>root.sortChildren = lambda c, o: None</code>).</s></p>

python sorting pyqt pyqt4 qtreewidget