qtsortingpyqtpyqt4qtreeview

Disable sorting of child items in QTreeView


I am using pyQt. How can I disable child items sorting in QTreeView/StandardItemModel?


Solution

  • You could use a QSortFilterProxyModel and reimplement its lessThan method.

    Alternatively, create a subclass of QStandardItem and reimplement its less than operator.

    Here's a simple example that demonstrates the latter approach:

    from random import sample
    from PyQt4 import QtGui, QtCore
    
    class Window(QtGui.QWidget):
        def __init__(self):
            QtGui.QWidget.__init__(self)
            self.view = QtGui.QTreeView(self)
            self.view.setHeaderHidden(True)
            self.model = QtGui.QStandardItemModel(self.view)
            self.view.setModel(self.model)
            parent = self.model.invisibleRootItem()
            keys = range(65, 91)
            for key in sample(keys, 10):
                item = StandardItem('Item %s' % chr(key), False)
                parent.appendRow(item)
                for key in sample(keys, 10):
                    item.appendRow(StandardItem('Child %s' % chr(key)))
            self.view.sortByColumn(0, QtCore.Qt.AscendingOrder)
            layout = QtGui.QVBoxLayout(self)
            layout.addWidget(self.view)
    
    class StandardItem(QtGui.QStandardItem):
        def __init__(self, text, sortable=True):
            QtGui.QStandardItem.__init__(self, text)
            self.sortable = sortable
    
        def __lt__(self, other):
            if getattr(self.parent(), 'sortable', True):
                return QtGui.QStandardItem.__lt__(self, other)
            return False
    
    if __name__ == '__main__':
    
        import sys
        app = QtGui.QApplication(sys.argv)
        window = Window()
        window.show()
        sys.exit(app.exec_())