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

PyQt表格选择菜单按钮背景色无法切换问题求助

问题:Qt表格选择菜单的悬停标记样式不生效

我正在为文本编辑器实现一个QMenu,用于快速创建最多10列8行的表格,效果类似Word或谷歌文档的表格选择菜单。使用QGridLayout布局10×8个GridButton,预期鼠标悬停按钮时,该按钮及行列坐标更小的按钮会通过修改hovered属性,配合QSS样式切换背景色以标记表格尺寸。

通过重写GridButton的enterEvent方法向父QWidgetAction发送坐标信号,在setMarkedButtons槽函数中为符合条件的按钮设置hovered属性,调用polish()更新样式,但背景色始终未变化。尝试过unpolish()、update()均无效,自定义fromStyle()加载样式表功能正常。

相关代码

class TableMenu(QtWidgets.QMenu):
    tableSize = QtCore.pyqtSignal(int, int)

    def __init__(self, parent=None) -> None:
        super().__init__(parent)
        self.setUI()

    def setUI(self) -> None:
        self.AC_TableGrid = TableGrid(self)
        self.AC_TableGrid.tableSize.connect(self.emitTableSize)
        self.addAction(self.AC_TableGrid)

    @QtCore.pyqtSlot(int, int)
    def emitTableSize(self, line: int, column: int) -> None:
        self.tableSize.emit(line, column)

class TableGrid(QtWidgets.QWidgetAction):
    tableSize = QtCore.pyqtSignal(int, int)

    def __init__(self, parent=None) -> None:
        super().__init__(parent)
        self.setUI()

    def setUI(self) -> None:
        self.Grid = QtWidgets.QWidget()
        self.ButtonLayout = QtWidgets.QGridLayout(self.Grid)
        self.ButtonLayout.setHorizontalSpacing(2)
        self.ButtonLayout.setVerticalSpacing(2)

        for iline in range(8):
            for icolumn in range(10):
                button = GridButton()
                button.line = iline+1
                button.column = icolumn+1
                button.entered.connect(self.setMarkedButtons)
                button.sizeSet.connect(self.getTableSize)
                self.ButtonLayout.addWidget(button, iline, icolumn)

        self.Grid.setLayout(self.ButtonLayout)

        self.setDefaultWidget(self.Grid)

    @QtCore.pyqtSlot(int, int)
    def setMarkedButtons(self, line: int, column: int) -> None:
        for i in range(self.ButtonLayout.count()):
            button = self.ButtonLayout.itemAt(i).widget()
            if button.column <= column and button.line <= line:
                print(button, button.line, button.column)
                if button.property("hovered"):
                    button.setProperty("hovered", False)
                else:
                    button.setProperty("hovered", True)

            else:
                button.setProperty("hovered", False)
            button.style().polish(button)            

    @QtCore.pyqtSlot(int, int)
    def getTableSize(self, line: int, column: int) -> None:
        self.tableSize.emit(line, column)

class GridButton(QtWidgets.QPushButton):
    entered = QtCore.pyqtSignal(int, int)
    sizeSet = QtCore.pyqtSignal(int, int)

    def __init__(self, parent=None) -> None:
        super().__init__(parent)
        self.setStyleSheet(fromStyle("GridButton")) # 快速加载样式表的便捷函数
        self.setProperty("hovered", False)
        self.setFixedSize(15, 15)
        self.connectSignals()
        self.line: int
        self.column: int

    def connectSignals(self) -> None:
        self.clicked.connect(self.emitCoordinates)

    def emitCoordinates(self) -> None:
        self.sizeSet.emit(self.line, self.column)
    
    def enterEvent(self, event: QtGui.QEnterEvent) -> None:
        self.entered.emit(self.line, self.column)
        print("Entered!")
        return super().enterEvent(event)

    def leaveEvent(self, a0: QtCore.QEvent) -> None:
        # 用于改变背景色的属性
        self.setProperty("hovered", False)
        self.style().polish(self)
        return super().leaveEvent(a0)

样式表(GridButton.qss)

QPushButton {
    background-color: white;
    border: 1px solid black;
    border-radius: 4px;
}

QPushButton [hovered='true'] {
    background-color: #75b4ec;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 14:46:02