当普通
QCheckbox
处于PartiallyChecked
状态时,左键单击它,它将变为Checked
状态。右键单击复选框不会执行任何操作。
我想修改一个复选框,以便右键单击与左键单击的效果相同,除非在
PartiallyChecked
状态下单击时,状态将更改为 Unchecked
而不是 Checked
。
这是我实现这一目标的尝试:
class MyCheckBox(QCheckBox):
def __init__(self):
super().__init__()
self.clicked.connect(lambda: self.setTristate(False))
def mousePressEvent(self, event: QMouseEvent):
if event.button() == Qt.MouseButton.RightButton:
event = QMouseEvent(event.type(), event.position(), Qt.MouseButton.LeftButton, event.buttons(), event.modifiers())
super().mousePressEvent(event)
def mouseReleaseEvent(self, event: QMouseEvent):
if event.button() == Qt.MouseButton.RightButton:
event = QMouseEvent(event.type(), event.position(), Qt.MouseButton.LeftButton, event.buttons(), event.modifiers())
if self.checkState() == Qt.CheckState.PartiallyChecked:
self.setCheckState(Qt.CheckState.Checked)
super().mouseReleaseEvent(event)
这将按预期工作,除非您按下复选框 > 在按住按钮的同时移开复选框 > 释放按钮。
mouseReleaseEvent
的自定义部分正在执行,而“本机”部分(在 super() 调用中)则没有执行。例如,不会发出 clicked
信号。
如何才能使发布事件的自定义部分以与本机部分相同的方式执行,即不在发布事件未选中时执行。
可能相关的观察:
当您按下复选框时,该框会变成阴影。当您离开盒子(按住)时,阴影会消失,当再次在盒子上移动时,阴影会再次出现。
此行为不会复制到我的右侧按钮的自定义复选框中。离开盒子时,阴影将保留。
为了在鼠标移动时提供正确的行为,您也必须覆盖
mouseMoveEvent()
,但在这种情况下,不同的按钮必须是事件 buttons()
的一部分(注意复数)。
nextCheckState()
内覆盖。使用简单的内部布尔属性,您可以相应地设置不同的状态。
class MyCheckBox(QCheckBox):
_isRightButton = False
...
def mouseMoveEvent(self, event: QMouseEvent):
if event.buttons() == Qt.MouseButton.RightButton:
event = QMouseEvent(
event.type(), event.position(),
Qt.MouseButton.NoButton,
Qt.MouseButton(Qt.MouseButton.LeftButton),
event.modifiers()
)
super().mouseMoveEvent(event)
def mouseReleaseEvent(self, event: QMouseEvent):
isRight = event.button() == Qt.MouseButton.RightButton
if isRight:
self._isRightButton = True
event = QMouseEvent(
event.type(), event.position(),
Qt.MouseButton.LeftButton,
event.buttons(),
event.modifiers()
)
super().mouseReleaseEvent(event)
if isRight:
self._isRightButton = False
def nextCheckState(self):
if self._isRightButton and self.checkState() == Qt.CheckState.PartiallyChecked:
self.setCheckState(Qt.CheckState.Unchecked)
else:
super().nextCheckState()