Aleksandar
Aleksandar

Reputation: 3661

Python: numerical sorting in QTableWidget

I need first column of my QTableWidget to be populated as: Row: 1, Row: 2...Row: 100 , but sorting doesn't work as expected (numerically). Sorting works fine with this code, but I don't get expected text:

for i in range(0, self.rows):
    item = QtGui.QTableWidgetItem()
    item.setData(Qt.DisplayRole, "Row: %s" %(i) )
    item.setData(Qt.EditRole, i)
    self.ui.tableWidget.setItem(i, 0, item)

I get: 1,2,3,4... instead of Row: 1, Row: 2, Row: 3... I expected that EditRole will be used for editing purposes (for numerical sorting, which works fine) but I also expected that text will be shown because it was set with DisplayRole. Can I do this that way somehow or writing function for purposes of sorting is the only way?

Upvotes: 3

Views: 3860

Answers (2)

ekhumoro
ekhumoro

Reputation: 120578

For QTableWidgetItem, the Qt.DisplayRole and Qt.EditRole are treated the same.

This means that, in the code:

item.setData(Qt.DisplayRole, "Row: %s" %(i) )
item.setData(Qt.EditRole, i)

the second line will simply overwrite the data set in the first line. So, effectively, there is no separate EditRole (unless the data and setData functions are reimplemented).

The standard way to alter the sort behaviour is to reimplement the less-than operator for QTableWidgetItem (which, by default, is hard-coded to use the DisplayRole data for sorting).

The following subclass will reproduce what Qt would normally do for numerical sorting:

class TableWidgetItem(QtGui.QTableWidgetItem):
    def __lt__(self, other):
        return (self.data(QtCore.Qt.UserRole).toLongLong() <
                other.data(QtCore.Qt.UserRole).toLongLong())

Upvotes: 7

Aleksandar
Aleksandar

Reputation: 3661

I am still interested why DisplayRole and EditRole doesn't do what I've expected, but I've solved the problem like this:

class MyTableWidgetItem(QtGui.QTableWidgetItem):
    def __init__(self, text, sortKey):
            QtGui.QTableWidgetItem.__init__(self, text, QtGui.QTableWidgetItem.UserType)
            self.sortKey = sortKey

    #Qt uses a simple < check for sorting items, override this to use the sortKey
    def __lt__(self, other):
            return self.sortKey < other.sortKey 

... populating table:

for i in range(0, self.rows):
    item = MyTableWidgetItem("Row: %s" %(i), i)
    self.ui.tableWidget.setItem(i, 1, item)

Upvotes: 6

Related Questions