eventFilter python demo

eventFilter python demo

一般网上能找到大量的c++代码关于过滤事件的例子,这里给一个简单完整的python PyQt5 的eventFilter例子,例子的代码原本是Qt4 来自于 https://stackoverflow.com/questions/28050397/eventfilter-on-a-qwidget-with-pyqt4 ,但是现在似乎都不怎么用QT4了,所以我稍微改了一下,变成Qt5使用 。(如有侵code 删)
完整代码如下:

xxxxxvm16$ cat eventF2.py 
#!/usr/bin/env python
# coding=utf-8
import sys
import random
import time
from PyQt5 import QtGui, QtCore
#from PyQt5.QtGui import *
from PyQt5.QtWidgets import QMainWindow, QApplication, QWidget, QVBoxLayout, QPushButton

class MainWindow(QMainWindow):
    def __init__(self):
        QMainWindow.__init__(self)
        self.__setUI()

    def __setUI(self, appTitle="[default title]"):
        self.statusBar()

        mainWidget = QWidget()
        vbox = QVBoxLayout()

        button = QPushButton("Hello")
        vbox.addWidget( button )

        points = DrawingPointsWidget()

        vbox.addWidget(points)

        mainWidget.setLayout(vbox)
        self.setCentralWidget(mainWidget)
        #self.installEventFilter(self)
        points.installEventFilter(self)
        button.installEventFilter(points) ##new_added

    def eventFilter(self, object, event):

        if event.type() == QtCore.QEvent.MouseMove: #if event.type() == QtCore.QEvent.HoverMove: 
            mousePosition = event.pos()
            cursor = QtGui.QCursor()

            self.statusBar().showMessage(
                "Mouse: [" + mousePosition.x().__str__() + ", " + mousePosition.y().__str__() + "]"
                + "\tCursor: [" + cursor.pos().x().__str__() + ", " + cursor.pos().y().__str__() + "]"

            )
            print("MouseMove obj: %s, self: %s"%(object, self))
            return True

        elif event.type() == QtCore.QEvent.MouseButtonPress:
            print("Mouse pressed obj: %s, self: %s"%(object, self))
            print("dir(self): %s"%dir(self))
            return True

        return False

class DrawingPointsWidget(QWidget):
    ""
    def __init__(self):
        super(QWidget, self).__init__()
        self.setMouseTracking(True)
        self.__setUI()

    def __setUI(self):

        self.setGeometry(300, 300, 280, 170)
        self.setWindowTitle('Points')
        self.show()

    def paintEvent(self, e):
        "Re-implemented method"

        print("paintEvent self: %s, e: %s"%(self, e))
        qp = QtGui.QPainter()
        qp.begin(self)
        self.drawPoints(qp)
        qp.end()

    def drawPoints(self, qp):

        qp.setPen(QtCore.Qt.red)

        "Need to get the size in case the window is resized -> generates a new paint event"
        size = self.size()

        for i in range(1000):
            x = random.randint(1, size.width()-1 )
            y = random.randint(1, size.height()-1 )
            qp.drawPoint(x, y)
    def eventFilter(self, obj, ev):
        #print("DrawingPointsWidget self: %s"%self)
        #time.sleep(1)
        if ev.type() == QtCore.QEvent.MouseButtonPress:
            print("self: %s, obj: %s, ev: %s,"%(self, obj, ev))
            return True
        return False 

def main():
    app = QApplication(sys.argv)
    #window = WidgetsWindow2()
    window = MainWindow()
    window.show()
    sys.exit(app.exec_())

if __name__ == "__main__":
    main()

关键的部分在于下面这一部分:

        #self.installEventFilter(self)
        points.installEventFilter(self)
        button.installEventFilter(points) ##new_added  !!!

注意一下几个要点:

  • 事件筛选器需要由要监视的对象设置
    points.installEventFilter(self) 要监视的对象是谁? points
    只有在 points 控件区域 移动鼠标 才会不断在状态栏 更新坐标

在这里插入图片描述
这里的self是干啥的??? 在这里当然是指 self: <__main__.MainWindow object at 0x7fa210a79ca8>主窗口控件对象
这个代码表明我们只能在 points区域去点鼠标才会在控制台输出Mouse pressed.

现在我们来解读 button.installEventFilter(points) 这是一个很奇怪的操作,最终导致我们点击button hello 会在控制台打印内容

self: <__main__.DrawingPointsWidget object at 0x7f4aa18e6f78>, obj: <PyQt5.QtWidgets.QPushButton object at 0x7f4aa18e6ca8>, ev: <PyQt5.QtGui.QMouseEvent object at 0x7f4a9a0a61f8>

疑问的当然是button.installEventFilter(points) 中的points,讲道理pointer所代表的控件和 button控件是分开的,为什么依然发生了这种过滤行为 。

如果我们把代码改一下,改成button.installEventFilter(self) #button.installEventFilter(points)

Mouse pressed obj: <__main__.DrawingPointsWidget object at 0x7f3fe635ef78>, self: <__main__.MainWindow object at 0x7f3fe635edc8>

Mouse pressed obj: <PyQt5.QtWidgets.QPushButton object at 0x7f3fe635ee58>, self: <__main__.MainWindow object at 0x7f3fe635edc8>

在这里插入图片描述
暂时先这样理解:
button.installEventFilter(points) 安装这个过滤事件,可以认为是 points这个控件,也就是说被监控的控件是button,当被监控的控件出现被过过滤的行为的时候,会触发points这个控件里面定义的eventFilter函数 。

可以借助 这篇文章 来理解 其中关系 https://blog.csdn.net/m0_37329910/article/details/88089582

猜你喜欢

转载自blog.csdn.net/m0_37329910/article/details/88088398