PyQt QPushButton 在按下 QPushButton 时离开事件
PyQt QPushButton leaveEvent while press QPushButton
我想要一个按钮。我正在尝试制作一个状态机,因此它将在 QState class.
中使用
如果鼠标光标悬停,按钮会改变它的颜色。
如果在按钮上松开鼠标左键,它应该可以工作。
如果鼠标左键在按钮上按下但在按钮外部松开,(按下时将光标拖到外部)按钮应该不起作用。
(因此用户可以通过拖出来取消他们的误点击。)
这是我的代码,但效果不佳。当我将光标拖到外面并释放鼠标按钮时,该按钮有效。
我测试了几个东西,现在我明白了一些。
按下鼠标按钮时,QPushButton.enterEvent 和 QPushButton.leaveEvent 不起作用。
当按下按钮时光标离开 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,0,0,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
Subclassing 和方法覆盖仅应在 class 未提供您需要的内容时进行,而您的情况并非如此。
clicked
signal does exactly what you describe: the signal is emitted when the user presses the left mouse button and releases it while the cursor is inside the button (and when click()
or animateClick()
以编程方式调用,但这不是重点)。
如果您还想在悬停按钮时更改外观,则必须使用 :hover 伪状态。请注意,要正确使用样式表选择器,您不能像以前那样使用简单的样式表语法,但 class 必须完全按照标准 CSS 指定。
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, 0, 0, 255);
}
''')
self.button.clicked.connect(self.someFunction)
一些注意事项:
rgb()
和 rgba()
语法接受 0 到 255 之间的整数或百分比,因此您使用的 alpha 值(0.5 和 1)不会按预期工作,因为它们将被认为实际上是透明的(分别为 0 和 1),因为非百分比值始终在 0-255 范围内;
- 伪状态可以链接,因此您还可以为
:hover
和[=18设置样式表规范=]
- 由于按钮的外观应始终反映其状态(最重要的是,无论何时按下),您至少应为
:pressed
状态添加 class 选择器;此外,使用 inset
和 outset
边框样式(而不是 solid
)也被认为是好的做法;请注意,它只适用于较暗的颜色,因此如果您想要“发白”的边框,请使用以下内容:
self.button.setStyleSheet('''
QPushButton {
color: white;
border: 2px outset lightGray;
background-color: rgba(250, 50, 150, 128);
}
QPushButton:pressed {
border-style: inset;
}
QPushButton:hover {
background-color: rgba(250, 0, 0, 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, 50, 150, 128);
}
''')
setMouseTracking()
is useful only when you need to track mouse movements when no mouse button is pressed, and are intercepted by mouseMoveEvent()
(你没有实现)通常总是调用鼠标移动在按下鼠标按钮后;
- enter 和 leave 事件只有在没有按下鼠标按钮时才会被接收:只要一个 widget(any widget)接收并接受一个
mousePressEvent()
,那个 widget将成为“鼠标抓取器”(参见 mouseGrabber()
and grabMouse()
)并且所有鼠标移动将仅由该小部件接收:no enter/leave/hover 事件将由任何其他小部件接收小部件,直到释放鼠标按钮;
- 虽然我能理解您的说法(“我搜索有助于实现我的目的的函数”),但您必须考虑到 Qt 是一个 庞大 框架,它是在25 年的跨度:它的所有 classes 已经提供了大部分常用的界面和功能,因此与其查找每个案例所需的内容,不如查看有关 [=75] 的文档=] 你在用,研究一下;考虑到您还应该 总是 对您正在使用的 class 的所有继承 class 执行相同的操作:在您的情况下,不要只看对于 QPushButton,但也请阅读有关 QAbstractButton 和 QWidget 的文档。
我想要一个按钮。我正在尝试制作一个状态机,因此它将在 QState class.
中使用如果鼠标光标悬停,按钮会改变它的颜色。
如果在按钮上松开鼠标左键,它应该可以工作。
如果鼠标左键在按钮上按下但在按钮外部松开,(按下时将光标拖到外部)按钮应该不起作用。 (因此用户可以通过拖出来取消他们的误点击。)
这是我的代码,但效果不佳。当我将光标拖到外面并释放鼠标按钮时,该按钮有效。
我测试了几个东西,现在我明白了一些。
按下鼠标按钮时,QPushButton.enterEvent 和 QPushButton.leaveEvent 不起作用。
当按下按钮时光标离开 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,0,0,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
Subclassing 和方法覆盖仅应在 class 未提供您需要的内容时进行,而您的情况并非如此。
clicked
signal does exactly what you describe: the signal is emitted when the user presses the left mouse button and releases it while the cursor is inside the button (and when click()
or animateClick()
以编程方式调用,但这不是重点)。
如果您还想在悬停按钮时更改外观,则必须使用 :hover 伪状态。请注意,要正确使用样式表选择器,您不能像以前那样使用简单的样式表语法,但 class 必须完全按照标准 CSS 指定。
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, 0, 0, 255);
}
''')
self.button.clicked.connect(self.someFunction)
一些注意事项:
rgb()
和rgba()
语法接受 0 到 255 之间的整数或百分比,因此您使用的 alpha 值(0.5 和 1)不会按预期工作,因为它们将被认为实际上是透明的(分别为 0 和 1),因为非百分比值始终在 0-255 范围内;- 伪状态可以链接,因此您还可以为
:hover
和[=18设置样式表规范=] - 由于按钮的外观应始终反映其状态(最重要的是,无论何时按下),您至少应为
:pressed
状态添加 class 选择器;此外,使用inset
和outset
边框样式(而不是solid
)也被认为是好的做法;请注意,它只适用于较暗的颜色,因此如果您想要“发白”的边框,请使用以下内容:
self.button.setStyleSheet('''
QPushButton {
color: white;
border: 2px outset lightGray;
background-color: rgba(250, 50, 150, 128);
}
QPushButton:pressed {
border-style: inset;
}
QPushButton:hover {
background-color: rgba(250, 0, 0, 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, 50, 150, 128);
}
''')
setMouseTracking()
is useful only when you need to track mouse movements when no mouse button is pressed, and are intercepted bymouseMoveEvent()
(你没有实现)通常总是调用鼠标移动在按下鼠标按钮后;- enter 和 leave 事件只有在没有按下鼠标按钮时才会被接收:只要一个 widget(any widget)接收并接受一个
mousePressEvent()
,那个 widget将成为“鼠标抓取器”(参见mouseGrabber()
andgrabMouse()
)并且所有鼠标移动将仅由该小部件接收:no enter/leave/hover 事件将由任何其他小部件接收小部件,直到释放鼠标按钮; - 虽然我能理解您的说法(“我搜索有助于实现我的目的的函数”),但您必须考虑到 Qt 是一个 庞大 框架,它是在25 年的跨度:它的所有 classes 已经提供了大部分常用的界面和功能,因此与其查找每个案例所需的内容,不如查看有关 [=75] 的文档=] 你在用,研究一下;考虑到您还应该 总是 对您正在使用的 class 的所有继承 class 执行相同的操作:在您的情况下,不要只看对于 QPushButton,但也请阅读有关 QAbstractButton 和 QWidget 的文档。