首页 > 解决方案 > 如果单击按钮,获取鼠标位置不起作用

问题描述

每当按下鼠标左键时,我都会尝试获取鼠标位置(在窗口中):

def mousePressEvent(self, event):
        print(event.pos())

但是,任何类型的交互式小部件都会覆盖它,例如 - 单击按钮不会打印鼠标位置,与行编辑和其他(可能除了标签)相同。即使单击了这些小部件,我如何获得鼠标位置?

标签: pythonpyqtpyqt5

解决方案


解释:

对于 QWidgets,您必须考虑:

  • 鼠标事件的传递是从顶部小部件(子)到底部小部件(父)。

  • 如果一个元素消耗了鼠标事件(即 use event.accept()),那么该事件将不再被传输。

解决方案:

如果要检测窗口上的鼠标事件,则可以通过事件过滤器在窗口本身(QWindow)上监视该事件:

import sys

from PyQt5.QtCore import pyqtSignal, QEvent, QObject, QPoint
from PyQt5.QtWidgets import (
    QApplication,
    QLineEdit,
    QPushButton,
    QTextEdit,
    QVBoxLayout,
    QWidget,
)


class MouseHelper(QObject):
    pressed = pyqtSignal(QPoint)
    released = pyqtSignal(QPoint)

    def __init__(self, window):
        super().__init__(window)
        self._window = window

        self.window.installEventFilter(self)

    @property
    def window(self):
        return self._window

    def eventFilter(self, obj, event):
        if self.window is obj:
            if event.type() == QEvent.MouseButtonPress:
                self.pressed.emit(event.pos())
            elif event.type() == QEvent.MouseButtonRelease:
                self.released.emit(event.pos())
        return super().eventFilter(obj, event)


class Widget(QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)

        button = QPushButton("Press me")
        lineedit = QLineEdit()
        textedit = QTextEdit()

        lay = QVBoxLayout(self)
        lay.addWidget(button)
        lay.addWidget(lineedit)
        lay.addWidget(textedit)


if __name__ == "__main__":
    app = QApplication(sys.argv)

    w = Widget()
    w.show()

    helper = MouseHelper(w.windowHandle())
    helper.pressed.connect(lambda point: print("pressed:", point))
    helper.released.connect(lambda point: print("released:", point))

    sys.exit(app.exec_())

推荐阅读