如何让QTableView单元格同时显示图标与文本?技术求助
实现QTableView单元格同时显示图标与文本
问题场景
- 仅显示图标时功能正常:
# L.append([QIcon(r"favicon.ico"), "file", "absolute_path", "modifytime"])
- 尝试同时显示图标与文本失败(错误使用QTableWidgetItem):
# L.append([QTableWidgetItem(QIcon(r"favicon.ico"), "file"), "file", "absolute_path", "modifytime"])
当前使用自定义QAbstractTableModel绑定QTableView,需要动态添加数据,原模型代码如下:
class FileModel(QAbstractTableModel): def __init__(self, data, header, *args, **kwargs): super(FileModel, self).__init__() self.datalist = data self.header = header def rowCount(self, parent=None, *args, **kwargs): return len(self.datalist) def columnCount(self, parent=None, *args, **kwargs): return len(self.header) def data(self, index, role=Qt.DisplayRole): if not index.isValid(): return None if role == Qt.DisplayRole or role == Qt.DecorationRole: return self.datalist[index.row()][index.column()] else: return None def headerData(self, col, orientation, role=None): if orientation == Qt.Horizontal and role == Qt.DisplayRole: return self.header[col] return None def append_data(self, x): self.datalist.append(x) self.layoutChanged.emit() def remove_row(self, row): self.datalist.pop(row) self.layoutChanged.emit() def remove_all(self): self.datalist.clear() self.layoutChanged.emit()
解决方案
核心问题分析
原模型的data方法对DisplayRole和DecorationRole返回相同数据,且错误地将QTableWidgetItem放入模型数据中——QAbstractTableModel不需要依赖QTableWidgetItem,模型只需管理原始数据,视图会根据角色渲染内容。
修改步骤
- 调整数据存储格式:将需要同时显示图标和文本的单元格数据存储为
(QIcon, 文本内容)的元组 - 修改模型的
data方法:根据不同角色返回对应的数据
修改后的模型data方法
def data(self, index, role=Qt.DisplayRole): if not index.isValid(): return None cell_data = self.datalist[index.row()][index.column()] # 处理显示文本的角色 if role == Qt.DisplayRole: if isinstance(cell_data, tuple) and len(cell_data) == 2 and isinstance(cell_data[0], QIcon): return cell_data[1] return cell_data # 处理显示图标的角色 elif role == Qt.DecorationRole: if isinstance(cell_data, tuple) and len(cell_data) == 2 and isinstance(cell_data[0], QIcon): return cell_data[0] return None
正确的数据添加方式
# 第一个单元格存储图标+文本的元组 L.append( [(QIcon(r"favicon.ico"), "file"), "file", "absolute_path", "modifytime"] )
完整修改后的模型代码
class FileModel(QAbstractTableModel): def __init__(self, data, header, *args, **kwargs): super(FileModel, self).__init__() self.datalist = data self.header = header def rowCount(self, parent=None, *args, **kwargs): return len(self.datalist) def columnCount(self, parent=None, *args, **kwargs): return len(self.header) def data(self, index, role=Qt.DisplayRole): if not index.isValid(): return None cell_data = self.datalist[index.row()][index.column()] if role == Qt.DisplayRole: if isinstance(cell_data, tuple) and len(cell_data) == 2 and isinstance(cell_data[0], QIcon): return cell_data[1] return cell_data elif role == Qt.DecorationRole: if isinstance(cell_data, tuple) and len(cell_data) == 2 and isinstance(cell_data[0], QIcon): return cell_data[0] return None def headerData(self, col, orientation, role=None): if orientation == Qt.Horizontal and role == Qt.DisplayRole: return self.header[col] return None def append_data(self, x): self.datalist.append(x) self.layoutChanged.emit() def remove_row(self, row): self.datalist.pop(row) self.layoutChanged.emit() def remove_all(self): self.datalist.clear() self.layoutChanged.emit()
内容的提问来源于stack exchange,提问作者高永献
相关产品推荐
相关产品推荐

