【发布时间】:2023-02-22 02:10:18
【问题描述】:
对于我的文本编辑器,我正在尝试实现 QMenu 以快速创建一个大小最多为 10 列和 8 行(行)的表格。它的外观和工作方式与您在 Word 或 Google Docs 中的类似,如下所示:
(https://i.stack.imgur.com/IxbPf.png)
在我的应用程序中,它看起来像这样:(https://i.stack.imgur.com/ciH7o.png)
你有一个 QGridLayout 的 10x8 按钮。如果将鼠标悬停在一个按钮上,它的背景颜色和所有具有较低列和行号的按钮的按钮颜色将改变它们的背景颜色以指示表格的大小。
我使用 enterEvent 通过网格坐标向父级 QWidgetAction 发出信号,并且每个具有与悬停按钮坐标相同或更低坐标的按钮都具有属性“悬停”更改。在相应的样式表中,此属性应该更改背景颜色,但并没有发生。
我已经多次查看代码,但我真的看不出为什么按钮的背景颜色没有改变的问题,所以如果有人有答案,我将不胜感激。
这是QMenu、带有按钮网格的QWidgetAction和特殊的QPushButton“GridButton”的代码:
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")) # A convenient function to quickly load a stylesheet.
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:
# This is the property to change the background colour
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;
}
我也尝试过类似的功能来更新外观,例如 unpolish() 或 update() 但它们也没有用。
我自己创建的便捷功能 fromStyle() 也可以正常工作。我查过了。所以这应该不是问题。
【问题讨论】:
-
拼写错误:删除
QPushButton和方括号之间的空格:选择器中的空格用于分隔类后代。此外,setMarkedButtons中的逻辑似乎是错误的(为什么要切换hovered属性?)。此外,为此使用按钮可能没有太多好处,而且可能会使事情不必要地复杂化:只需使用自定义 QWidget 子类并手动进行绘制。在任何情况下,为每个按钮单独设置 qss 是没有意义的:只需在小部件父级(self.Grid,它也应该不是有一个大写的名字,因为它不是一个类)。
标签: python pyqt qtstylesheets qmenu qwidgetaction