PyQt QPushButton在按下QPushButton时离开事件

问题描述

我想要一个按钮。我正在尝试制作状态机,因此将在QState类中使用它。

如果鼠标光标悬停,则按钮将更改其颜色。

如果在该按钮上释放了鼠标左键,则应该可以使用。

如果在该按钮上按下了鼠标左键,但在按钮外侧释放了鼠标左键,(按下时将光标拖动到外部)该按钮不起作用。 (因此用户可以通过拖出操作来取消未命中的点击。)

这是我的代码,但效果不佳。当我将光标拖到外部并释放鼠标按钮时,该按钮有效。

我测试了几件事,现在我明白了。

  1. 在按下鼠标按钮时,QPushButton.enterEvent和QPushButton.leaveEvent不起作用。

  2. 当按下按钮时光标离开QPushButton时,似乎QPushButton.released发出信号。

如何设置此按钮?

class MyButton(QtWidgets.QPushButton):
    selected = QtCore.pyqtSignal(bool)

    def __init__(self,parent=None):
        super().__init__(parent)
        self.setMouseTracking(True)
        self.is_hover = False

    def enterEvent(self,event):
        self.setStyleSheet\
            ("color: black; border-style: solid;\
                border-width: 2px; border-color: white;\
                    background-color: rgba(250,1);")            
        self.is_hover = True
        print('is_hover = True')

    def leaveEvent(self,event):
        self.setStyleSheet\
            ("color: white; border-style: solid;\
                border-width: 2px; border-color: white;\
                    background-color: rgba(250,50,150,0.5);")
        self.is_hover = False
        print('is_hover = False')

    def mouseReleaseEvent(self,event):
        if event.button() == QtCore.Qt.LeftButton:
            if self.is_hover:
                self.selected.emit(True)
            else:
                return
        else:            
            return

解决方法

仅当类没有提供您所需要的东西时才应进行子类化和方法重写,而这不是您的情况。

clicked信号完全符合您的描述:当用户按下鼠标左键并在光标 内释放鼠标时(以及当{{ 3}}或click()以编程方式被调用,但这不是重点。

如果要在悬停按钮时也更改外观,则必须使用animateClick()伪状态。请注意,要正确使用样式表选择器,您不能像使用样式表语法那样使用简单的样式表语法,但是必须完全按照标准CSS的方式指定 class

    self.button = QPushButton()
    self.button.setStyleSheet('''
        QPushButton {
            color: white;
            border: 2px solid white;
            background-color: rgba(250,50,150,128);
        }

        QPushButton:hover {
            background-color: rgba(250,255);
        }
    ''')
    self.button.clicked.connect(self.someFunction)

一些注意事项:

  • rgb()rgba()语法接受0到255之间的整数或百分比,因此您使用的alpha值(0.5和1)将无法正常工作,因为实际上会考虑使用它们透明(分别为0和1),因为非百分比值始终在0-255范围内;
  • 可以将
  • 伪状态链接为 ,因此您还可以为两者 :hover:pressed
  • 设置样式表规范
  • 由于按钮的外观应始终反映其状态(最重要的是,无论是否按下按钮),因此您至少应为:pressed状态添加类选择器;同样,使用insetoutset边框样式(而不是solid)也被认为是一种好习惯;请注意,它仅适用于较深的颜色,因此,如果要使用“发白”的边框,请使用以下命令:
    self.button.setStyleSheet('''
        QPushButton {
            color: white;
            border: 2px outset lightGray;
            background-color: rgba(250,128);
        }
        QPushButton:pressed {
            border-style: inset;
        }
        QPushButton:hover {
            background-color: rgba(250,255);
        }
        QPushButton:hover:pressed {
            /* since no background was set for pressed,hover state takes
            precedence,so we need to specify the "default" color again here */
            background-color: rgba(250,128);
        }
    ''')
  • :hover仅在您需要在没有按下鼠标键的情况下跟踪鼠标的移动时才有用,并且被setMouseTracking()(您未实现)拦截(通常总是要求鼠标移动) 之后,按下了鼠标按钮;
  • 进入和离开事件仅在没有按下鼠标按钮的情况下才会接收:一旦小部件( any 小部件)接收并接受mousePressEvent(),该小部件将成为“鼠标”抓取程序”(请参阅​​mouseMoveEvent()mouseGrabber()),并且所有鼠标移动将仅由该窗口小部件接收: enter / leave / hover事件将被其他任何窗口小部件接收,直到释放鼠标按钮;
  • 虽然我能理解您的声明(“我搜索有助于实现目标的功能”),但您必须考虑Qt是一个巨大框架,该框架已经开发了25年:它的所有类都已经提供了大多数常用的接口和功能,因此与其查找每种情况所需的内容,不如去阅读有关所用类的文档并进行研究;考虑到您还应该始终对正在使用的类的所有继承的类执行相同的操作:在您的情况下,不仅要查找QPushButton,还要阅读有关QAbstractButton和{{ 3}}。