如何完全实现QCheckBox的自定义鼠标右键功能

问题描述 投票:0回答:1

当普通

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
信号。

如何才能使发布事件的自定义部分以与本机部分相同的方式执行,即不在发布事件未选中时执行。

可能相关的观察:
当您按下复选框时,该框会变成阴影。当您离开盒子(按住)时,阴影会消失,当再次在盒子上移动时,阴影会再次出现。
此行为不会复制到我的右侧按钮的自定义复选框中。离开盒子时,阴影将保留。

python pyqt pyqt6 qcheckbox
1个回答
0
投票

为了在鼠标移动时提供正确的行为,您也必须覆盖

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()
© www.soinside.com 2019 - 2024. All rights reserved.