Qt6:QTableView选中高亮自定义失效问题求助
问题
想自定义QTableView选中项的高亮区域,但将QListView中可用的代码迁移过来后,出现自定义高亮与默认高亮同时显示的异常情况。
QListView 可行示例代码
from PySide6 import QtCore as qtc from PySide6 import QtGui as qtg from PySide6 import QtWidgets as qtw class ListItemsDelegate(qtw.QStyledItemDelegate): def paint(self, painter: qtg.QPainter, option: qtw.QStyleOptionViewItem, index: qtc.QModelIndex) -> None: if option.state & qtw.QStyle.StateFlag.State_Selected: painter.fillRect( qtc.QRect( option.rect.left(), option.rect.top(), 20, option.rect.height() ), qtc.Qt.GlobalColor.blue, ) option.state &= ~qtw.QStyle.StateFlag.State_Selected option.state &= ~qtw.QStyle.StateFlag.State_HasFocus painter.drawText(option.rect.topLeft(), "text") app = qtw.QApplication() model = qtc.QStringListModel([1, 2, 3]) view = qtw.QListView() view.setModel(model) view.setItemDelegate(ListItemsDelegate()) view.show() app.exec()
效果:仅显示左侧20px宽度的蓝色高亮,无默认选中背景。
QTableView 异常示例代码
from PySide6 import QtCore as qtc from PySide6 import QtGui as qtg from PySide6 import QtWidgets as qtw class TableItemsDelegate(qtw.QStyledItemDelegate): def paint(self, painter: qtg.QPainter, option: qtw.QStyleOptionViewItem, index: qtc.QModelIndex) -> None: if option.state & qtw.QStyle.StateFlag.State_Selected: highlight_rect = qtc.QRect(option.rect) highlight_rect.adjust(20, 20, -20, -20) painter.fillRect( highlight_rect, qtc.Qt.GlobalColor.blue, ) option.state &= ~qtw.QStyle.StateFlag.State_Selected option.state &= ~qtw.QStyle.StateFlag.State_HasFocus painter.drawText(option.rect.topLeft(), "text") class TableModel(qtc.QAbstractTableModel): def data(self, *args) -> int: return 1 def rowCount(self, *args) -> int: return 5 def columnCount(self, *args) -> int: return 5 app = qtw.QApplication() view = qtw.QTableView() view.setModel(TableModel()) view.setItemDelegate(TableItemsDelegate()) view.show() app.exec()
效果:自定义的缩小版蓝色高亮与默认的全单元格灰色高亮同时显示。
问题原因
- QListView的默认选中背景由ItemDelegate负责绘制,所以在Delegate中清除
State_Selected状态后,默认高亮不会被绘制; - QTableView的默认选中背景由视图本身(QTableView)绘制,而非ItemDelegate。即便在Delegate中清除了选中状态,视图仍会自行绘制默认选中高亮,导致两个高亮叠加。
解决方法
方案1:禁用QTableView默认选中背景(推荐)
在创建QTableView后添加样式表代码,让视图不再绘制默认选中背景:
view.setStyleSheet("QTableView::item:selected { background: transparent; }")
方案2:重写QTableView的paintEvent(灵活但繁琐)
如果需要更复杂的绘制控制,可以重写QTableView的paintEvent方法,跳过默认选中背景的绘制逻辑,但这种方式代码量更大,一般优先选择方案1。
内容的提问来源于stack exchange,提问作者Neat
相关产品推荐
相关产品推荐

