微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

PyQt6 不调用任何悬停在框架上的事件

如何解决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 举报,一经查实,本站将立刻删除。