Sort a PySide.QtGui.QTreeWidget by an alpha numeric column
pyqt, pyside, python, qtreewidget, sorting
Solution
You can re-implement the less-than operator of your tree-widget items and use whatever algorithm you like to control sorting:
class TreeWidgetItem(QtGui.QTreeWidgetItem):
def __lt__(self, other):
return funky_sort_key(self.text(), other.text())
Using this method, you don't even need to sort by text - you could also sort by the item-data (or whatever).
Problem
I would like to sort a `QTreeWidget` by the `alpha_numeric` column. Update: Following ekhumoro's example, I re-implemented the `QTreeWidgetItem` `__lt__` method to use the desired natural sorting. Relevant code: ``` class TreeWidgetItem(QtGui.QTreeWidgetItem): def __lt__(self, other): column = self.treeWidget().sortColumn() key1 = self.text(column) key2 = other.text(column) return self.natural_sort_key(key1) < self.natural_sort_key(key2) @staticmethod def natural_sort_key(key): regex = '(\d*\.\d+|\d+)' parts = re.split(regex, key) return tuple((e if i % 2 == 0 else float(e)) for i, e in enumerate(parts)) ``` Updated full working example: ``` import sys import re from PySide import QtGui, QtCore data = [ {"name": "Apple", "alpha_numeric": "11"}, {"name": "Apple", "alpha_numeric": "125b"}, {"name": "Apple", "alpha_numeric": "125a"}, {"name": "Apple", "alpha_numeric": "3"}, {"name": "Orange", "alpha_numeric": "11"}, {"name": "Orange", "alpha_numeric": "125b"}, {"name": "Orange", "alpha_numeric": "125a"}, {"name": "Orange", "alpha_numeric": "3"}, ] # re-implement the QTreeWidgetItem class TreeWidgetItem(QtGui.QTreeWidgetItem): def __lt__(self, other): column = self.treeWidget().sortColumn() key1 = self.text(column) key2 = other.text(column) return self.natural_sort_key(key1) < self.natural_sort_key(key2) @staticmethod def natural_sort_key(key): regex = '(\d*\.\d+|\d+)' parts = re.split(regex, key) return tuple((e if i % 2 == 0 else float(e)) for i, e in enumerate(parts)) class MainWindow(QtGui.QMainWindow): def __init__(self): super(MainWindow, self).__init__() self.resize(300, 300) self.table = None self.ui() def ui(self): # setup the table self.table = QtGui.QTreeWidget() self.table.setRootIsDecorated(False) self.table.setAlternatingRowColors(True) self.table.setSortingEnabled(True) # columns and widths column_names = ['Name', 'Alpha Numeric'] self.table.setColumnCount(2) self.table.setColumnWidth(0, 150) self.table.setColumnWidth(1, 150) self.table.setHeaderLabels(column_names) # row data for row in data: column = TreeWidgetItem(self.table) column.setSizeHint(0, QtCore.QSize(30, 30)) column.setText(0, row['name']) column.setText(1, row['alpha_numeric']) # sort self.table.sortByColumn(1, QtCore.Qt.AscendingOrder) self.table.sortByColumn(0, QtCore.Qt.AscendingOrder) # setup the layout self.setCentralWidget(self.table) if __name__ == '__main__': app = QtGui.QApplication(sys.argv) window = MainWindow() window.show() sys.exit(app.exec_()) ```