在QAbstractTableModel中为大型pandas DataFrame指定列设置十六进制显示格式
解决方案
仅需修改PandasModel类的data方法的显示逻辑即可实现需求,无需改动if __name__ == '__main__'代码块的任何内容。核心逻辑为在返回显示内容前先判断当前列的名称,针对不同列执行差异化的格式化规则:
A列:保持原有十进制整型格式输出B列:将单个整型值转换为十六进制字符串输出C列:遍历单元格内存储的整型列表,逐个元素转为十六进制后拼接为字符串输出
修改后的完整可运行代码如下:
from PyQt5 import QtCore, QtWidgets import numpy as np import sys import pandas as pd class raw_data_table_view(QtWidgets.QTableView): def __init__(self, data): QtWidgets.QTableView.__init__(self) self.setSelectionMode(QtWidgets.QAbstractItemView.NoSelection) self.horizontalHeader().setSectionResizeMode(QtWidgets.QHeaderView.ResizeToContents) model = PandasModel(data) self.setModel(model) class PandasModel(QtCore.QAbstractTableModel): def __init__(self, data, parent=None): QtCore.QAbstractTableModel.__init__(self, parent) self._data = np.array(data.values) self._cols = data.columns self.r, self.c = np.shape(self._data) def rowCount(self, parent=None): return self.r def columnCount(self, parent=None): return self.c def data(self, index, role=QtCore.Qt.DisplayRole): if index.isValid(): if role == QtCore.Qt.DisplayRole: col_name = self._cols[index.column()] cell_val = self._data[index.row(), index.column()] # 按列名区分显示格式 if col_name == 'A': return str(cell_val) elif col_name == 'B': # 如需去掉0x前缀、固定位数可改为 f"{cell_val:02x}" 等自定义格式 return hex(cell_val) elif col_name == 'C': # 列表元素转十六进制后用逗号分隔,可自行调整分隔符 return ', '.join([hex(i) for i in cell_val]) return None def headerData(self, p_int, orientation, role): if role == QtCore.Qt.DisplayRole: if orientation == QtCore.Qt.Horizontal: return self._cols[p_int] elif orientation == QtCore.Qt.Vertical: return p_int return None if __name__ == '__main__': app = QtWidgets.QApplication(sys.argv) length = 300000 df = pd.DataFrame(np.random.randint(0, 100, size=(length, 2)), columns=list('AB')) df['C'] = list(np.random.randint(0, 255, size=(length, 8))) window = raw_data_table_view(df) window.resize(400, 800) window.show() sys.exit(app.exec_())
如果需要调整十六进制的显示样式,比如不需要0x前缀、固定显示2位十六进制字符,只需要将对应的hex(x)替换为格式化字符串即可,例如f"{x:02x}"对应小写两位十六进制,f"{x:02X}"对应大写两位十六进制。
内容的提问来源于stack exchange,提问作者RMRiver
相关产品推荐
相关产品推荐

