You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在不修改选择模式和样式表的情况下禁用QTableWidget选中单元格高亮?

问题

现有一个实现了单元格颜色切换的网格示例,但运行时自定义设置的单元格颜色会被选中高亮效果遮挡。要求不能修改选择模式(需保留选择范围以实现单行内批量单元格上色),也不能调整样式表(避免多行单元格被高亮),问是否可以完全禁用/绕过高亮颜色的绘制事件?

示例代码:

import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *

class MainWindow(QMainWindow):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.setGeometry(100, 100, 750, 750)

        self.rows=60
        self.columns=50
        self.tableWidget=QTableWidget(self.rows, self.columns)
        self.tableWidget.horizontalHeader().hide()
        self.tableWidget.verticalHeader().hide()
        
        self.activated={}
        self.item={}
        for r in range(self.rows):
            for c in range(self.columns):
                self.activated[r,c]=False
                self.item[r,c]=QTableWidgetItem()
                self.tableWidget.setItem(r,c,self.item[r,c])

        self.tableWidget.setFocusPolicy(Qt.NoFocus)
        #self.tableWidget.setSelectionMode(QAbstractItemView.NoSelection)
        #self.tableWidget.setStyleSheet("""QTableView:item:selected{selection-background-color: rgb(100,100,150);}""")
        #self.tableWidget.setStyleSheet("""QTableView:item:selected{selection-background-color: transparent;}""")
        self.tableWidget.setEditTriggers(QTableWidget.NoEditTriggers)
        
        self.tableWidget.cellClicked.connect(self.dothing)
        self.tableWidget.cellDoubleClicked.connect(self.dothing)

        self.setCentralWidget(self.tableWidget)
    
    def dothing(self,r,c):
        if self.activated[r,c]: 
            self.activated[r,c]=False
            self.item[r,c].setBackground(QColor(255,255,255))

        else: 
            # 修正原代码笔误:循环变量应为row而非column,避免键不存在错误
            for row in range(self.rows):
                self.activated[row,c]=False
                self.item[row,c].setBackground(QColor(255,255,255))
            self.activated[r,c]=True
            self.item[r,c].setBackground(QColor(100,100,150))

app = QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec()
解决方案

可以通过自定义QTableWidgetItem并重写其paint方法绕过高亮颜色绘制,完全控制单元格背景显示,同时保留选择功能。

核心思路:在绘制单元格时,移除选中状态标记,让Qt不再绘制高亮背景,直接使用自定义设置的背景色,同时保留文本等其他内容的正常绘制。

修改后的完整代码:

import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *

class CustomTableItem(QTableWidgetItem):
    def paint(self, painter, option, index):
        # 复制选项对象,避免修改原对象影响其他单元格绘制
        opt = QStyleOptionViewItem(option)
        # 移除选中状态标记,取消高亮背景绘制
        opt.state &= ~QStyle.State_Selected
        # 调用父类paint方法,使用修改后的选项
        super().paint(painter, opt, index)

class MainWindow(QMainWindow):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.setGeometry(100, 100, 750, 750)

        self.rows=60
        self.columns=50
        self.tableWidget=QTableWidget(self.rows, self.columns)
        self.tableWidget.horizontalHeader().hide()
        self.tableWidget.verticalHeader().hide()
        
        self.activated={}
        self.item={}
        for r in range(self.rows):
            for c in range(self.columns):
                self.activated[r,c]=False
                # 使用自定义单元格类替代默认类
                self.item[r,c]=CustomTableItem()
                self.tableWidget.setItem(r,c,self.item[r,c])

        self.tableWidget.setFocusPolicy(Qt.NoFocus)
        self.tableWidget.setEditTriggers(QTableWidget.NoEditTriggers)
        
        self.tableWidget.cellClicked.connect(self.dothing)
        self.tableWidget.cellDoubleClicked.connect(self.dothing)

        self.setCentralWidget(self.tableWidget)
    
    def dothing(self,r,c):
        if self.activated[r,c]: 
            self.activated[r,c]=False
            self.item[r,c].setBackground(QColor(255,255,255))

        else: 
            for row in range(self.rows):
                self.activated[row,c]=False
                self.item[row,c].setBackground(QColor(255,255,255))
            self.activated[r,c]=True
            self.item[r,c].setBackground(QColor(100,100,150))

app = QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec()

关键说明

  • 自定义CustomTableItem类通过修改绘制选项,彻底取消了选中高亮背景的绘制,完全保留自定义背景色的显示。
  • 原有的选择功能不受影响,依然可以通过selectedItems()等方法获取选中单元格,满足单行批量上色的需求。
  • 无需修改选择模式或样式表,完美规避高亮遮挡自定义颜色的问题。

内容的提问来源于stack exchange,提问作者rllysleepy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 14:52:56