如何解决PyQt6 不调用任何悬停在框架上的事件
我的目标是检测用户何时悬停或停止悬停在框架上,但是每当我尝试使用 eventFilter 检测时,都没有运行的事件显示该情况。 hoverEnter、hoverLeave 和 hoverMouseMove 的事件 ID 是 127、128 和 129,但是如果您运行代码,您会发现它们只是不出现。这是失败的代码:
import sys
from PyQt6.QtCore import *
from PyQt6.QtGui import *
from PyQt6.QtWidgets import *
class MainApp(QWidget):
def __init__(self):
super().__init__()
self.setwindowTitle("Test Window")
self.resize(300,200)
self.outerLayout = QHBoxLayout()
self.outerLayout.setContentsMargins(50,50,50)
self.frame = qframe()
self.frame.setStyleSheet("background-color: lightblue;")
self.innerLayout = QHBoxLayout(self.frame)
self.label = QLabel(self.frame)
self.label.setText("Example Frame")
self.innerLayout.addWidget(self.label)
self.outerLayout.addWidget(self.frame)
self.setLayout(self.outerLayout)
def eventFilter(self,obj,event):
if event.type() == 127:
print("hovered")
elif event.type() == 128:
print("no longer hovered")
elif event.type() == 129:
print("hover move event")
print(event.type())
return True
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MainApp()
window.installEventFilter(window)
window.show()
sys.exit(app.exec())
我的最终目标是能够检测到 qframe 何时被点击。我想我会尝试通过检查鼠标点击来做到这一点,如果鼠标悬停在框架上,则触发该功能。
解决方法
首先需要注意的是,clicked 不是事件而是信号。当按钮接收到 MouseButtonRelease 事件时,会发出按钮点击信号。
在这个答案中,我将至少展示以下方法来实现 QFrame 中的点击信号。
-
覆盖 mouseReleaseEvent
import sys from PyQt6.QtCore import pyqtSignal,pyqtSlot from PyQt6.QtWidgets import QApplication,QFrame,QHBoxLayout,QLabel,QWidget class Frame(QFrame): clicked = pyqtSignal() def mouseReleaseEvent(self,event): super().mouseReleaseEvent(event) self.clicked.emit() class MainApp(QWidget): def __init__(self): super().__init__() self.setWindowTitle("Test Window") self.resize(300,200) self.outerLayout = QHBoxLayout(self) self.outerLayout.setContentsMargins(50,50,50) self.frame = Frame() self.frame.setStyleSheet("background-color: lightblue;") self.label = QLabel(text="Example Frame") self.innerLayout = QHBoxLayout(self.frame) self.innerLayout.addWidget(self.label) self.outerLayout.addWidget(self.frame) self.frame.clicked.connect(self.handle_clicked) @pyqtSlot() def handle_clicked(self): print("frame clicked") if __name__ == "__main__": app = QApplication(sys.argv) window = MainApp() window.show() sys.exit(app.exec())
-
使用事件过滤器:
import sys from PyQt6.QtCore import QEvent from PyQt6.QtWidgets import QApplication,QWidget class MainApp(QWidget): def __init__(self): super().__init__() self.setWindowTitle("Test Window") self.resize(300,50) self.frame = QFrame() self.frame.setStyleSheet("background-color: lightblue;") self.label = QLabel(text="Example Frame") self.innerLayout = QHBoxLayout(self.frame) self.innerLayout.addWidget(self.label) self.outerLayout.addWidget(self.frame) self.frame.installEventFilter(self) # for move mouse # self.frame.setMouseTracking(True) def eventFilter(self,obj,event): if obj is self.frame: if event.type() == QEvent.Type.MouseButtonPress: print("press") # for move mouse # elif event.type() == QEvent.Type.MouseMove: # print("move") elif event.type() == QEvent.Type.MouseButtonRelease: print("released") return super().eventFilter(obj,event) if __name__ == "__main__": app = QApplication(sys.argv) window = MainApp() window.show() sys.exit(app.exec())
加号
O 尝试的很大一部分错误在于,通过执行 window.installEventFilter(window)
,它只侦听来自窗口本身的事件,而不是来自 QFrame 的事件。解决方案是将 QFrame 事件发送到类 window.frame.installEventFilter(window)
。
另一方面,不要使用数字代码,而是使用枚举,因为它们更具可读性。
另一方面,对于鼠标事件,必须启用Qt::WA_Hover
属性(阅读docs了解更多信息)
import sys
from PyQt6.QtCore import QEvent,Qt
from PyQt6.QtWidgets import QApplication,50)
self.frame = QFrame()
self.frame.setStyleSheet("background-color: lightblue;")
self.label = QLabel(text="Example Frame")
self.innerLayout = QHBoxLayout(self.frame)
self.innerLayout.addWidget(self.label)
self.outerLayout.addWidget(self.frame)
self.frame.setAttribute(Qt.WidgetAttribute.WA_Hover)
self.frame.installEventFilter(self)
def eventFilter(self,event):
if obj is self.frame:
if event.type() == QEvent.Type.HoverEnter:
print("enter")
elif event.type() == QEvent.Type.HoverMove:
print("move")
elif event.type() == QEvent.Type.HoverLeave:
print("leave")
return super().eventFilter(obj,event)
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MainApp()
window.show()
sys.exit(app.exec())
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。