PyQt6 QStyledItemDelegate设置TableView列文本前景色无效问题
PyQt6 QTableView指定列设置前景色失效修复
问题现象
- 目标:为QTableView指定列设置红色前景文本,选择继承
QStyledItemDelegate重写initStyleOption()实现,此前重写paint()方法可实现红色文本,但存在项重复绘制异常 - 运行表现:代码无报错,但目标列文本始终为默认黑色,未达到预期效果
原问题代码:
class MainGUI(qt.QMainWindow): def __init__(self): super().__init__() self.resize(653, 500) frame = qt.QFrame() self.setCentralWidget(frame) self.grid = qt.QGridLayout(frame) self.model = QStandardItemModel() self.view = qt.QTableView() self.view.setModel(self.model) self.view.setItemDelegate(TableDisplay()) self.grid.addWidget(self.view, 0, 0) lst1 = [QStandardItem('testing...')] * 10 lst2 = [QStandardItem('more...')] * 10 self.model.appendColumn(lst1) self.model.appendColumn(lst2) class TableDisplay(qt.QStyledItemDelegate): def initStyleOption(self, option, index): super(TableDisplay, self).initStyleOption(option, index) if index.column() == 1: option.palette.setColor(QPalette.ColorRole(0), Qt.GlobalColor.red)
失效原因
- 颜色角色选择错误:
QPalette.ColorRole(0)对应WindowText角色,用于窗口非编辑区域的文本绘制,QTableView项文本默认使用QPalette.ColorRole.Text角色读取颜色 - 未指定调色板颜色组:Qt调色板按控件状态分为Normal(正常未选中)、Selected(选中)、Disabled(禁用)多个独立分组,未指定分组设置颜色无法覆盖所有状态下的文本表现
- 存在浅拷贝隐患:
[QStandardItem('xxx')] * 10写法会让列表内10个元素引用同一个QStandardItem实例,后续修改单个单元格属性会出现全列联动异常
修正后实现
from PyQt6.QtGui import QPalette, QStandardItem from PyQt6 import QtWidgets as qt from PyQt6.QtCore import Qt class TableDisplay(qt.QStyledItemDelegate): def initStyleOption(self, option, index): super().initStyleOption(option, index) # 列索引从0开始计数,column()==1对应视觉上第二列,需要第一列改为0即可 if index.column() == 1: # 覆盖所有交互状态下的文本颜色 option.palette.setColor( QPalette.ColorGroup.Normal, QPalette.ColorRole.Text, Qt.GlobalColor.red ) option.palette.setColor( QPalette.ColorGroup.Selected, QPalette.ColorRole.Text, Qt.GlobalColor.red ) option.palette.setColor( QPalette.ColorGroup.Disabled, QPalette.ColorRole.Text, Qt.GlobalColor.red ) class MainGUI(qt.QMainWindow): def __init__(self): super().__init__() self.resize(653, 500) frame = qt.QFrame() self.setCentralWidget(frame) self.grid = qt.QGridLayout(frame) self.model = qt.QStandardItemModel() self.view = qt.QTableView() self.view.setModel(self.model) self.view.setItemDelegate(TableDisplay()) self.grid.addWidget(self.view, 0, 0) # 用列表推导式生成独立的QStandardItem实例,避免浅拷贝问题 lst1 = [QStandardItem('testing...') for _ in range(10)] lst2 = [QStandardItem('more...') for _ in range(10)] self.model.appendColumn(lst1) self.model.appendColumn(lst2)
补充:如果不需要处理选中/禁用状态的颜色一致性,仅设置Normal分组即可生效。
内容的提问来源于stack exchange,提问作者malonn
相关产品推荐
相关产品推荐

