Reputation: 3661
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
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
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