I want to know the best way of sorting hexadecimal numbers inside the QTableWidget.
Currently what i do is convert all the hexadecimal values then sort it (ascending/descending). But my problem is since i did convert it to decimal. The values shown in table is in decimal. I want to sort hexadecimal without changing the value shown in table
Here is my current implementation:
from PySide2.QtCore import Qt
from PySide2.QtWidgets import QTableWidget
class NumericData(QTableWidgetItem):
def __lt__(self, other):
return (self.data(Qt.UserRole) < other.data(Qt.UserRole))
class Window(QTableWidget):
def __init__(self):
super(Window, self).__init__(4, 2)
for column, values in enumerate((
('ABCD', '1DCA', 'BD23', 'FFFFFFFF'),
(1,2,3,4)
)):
for row, value in enumerate(values):
if column == 0:
value = str(int(value, 16))
else:
value = str(value)
item = NumericData(value)
item.setData(Qt.UserRole, value)
self.setItem(row, column, item)
self.setSortingEnabled(True)
self.sortItems(0, Qt.AscendingOrder)
Here is the sample table
|--Values--|
|ABCD |
|1BCD |
|DEC1 |
|123 |
|2105 |
|AAAAAAAA |
It is not necessary to use a new role just to save the conversion since if the user changes the value you would have to recalculate that value, you can only pass in the role Qt::DisplayRole.
Considering this I have implemented the following example:
from PySide2 import QtCore, QtGui, QtWidgets
class HexDelegate(QtWidgets.QStyledItemDelegate):
def createEditor(self, parent, option, index):
editor = QtWidgets.QSpinBox(parent)
editor.setMaximum(2147483647)
editor.setMinimum(-2147483647 - 1)
editor.setDisplayIntegerBase(16)
fnt = editor.font()
fnt.setCapitalization(QtGui.QFont.AllUppercase)
editor.setFont(fnt)
return editor
def setEditorData(self, editor, index):
editor.setValue(int(index.data(QtCore.Qt.DisplayRole), 16))
def setModelData(self, editor, model, index):
value = ('{:x}'.format(editor.value())).upper()
model.setData(index, value, QtCore.Qt.DisplayRole)
class NumericData(QtWidgets.QTableWidgetItem):
def __lt__(self, other):
return int(self.data(QtCore.Qt.DisplayRole), 16) < int(
other.data(QtCore.Qt.DisplayRole), 16
)
class Window(QtWidgets.QTableWidget):
def __init__(self):
super(Window, self).__init__(4, 2)
delegate = HexDelegate(self)
self.setItemDelegateForColumn(0, delegate)
data = ("ABCD", "1DCA", "BD23", "FFFF"), (1, 2, 3, 4)
for row, values in enumerate(zip(*data)):
for col, value in enumerate(values):
it = QtWidgets.QTableWidgetItem()
it.setData(QtCore.Qt.DisplayRole, value)
self.setItem(row, col, it)
self.setSortingEnabled(True)
self.sortItems(0, QtCore.Qt.AscendingOrder)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = Window()
w.show()
sys.exit(app.exec_())