QGraphicsView如何接收鼠标移动事件?

How does QGraphicsView receive mouse move events?

简而言之,我想在 QGraphicsView 上跟踪鼠标坐标。

This answer 适用于 QLabel 对象,但当我切换到 QGraphicsView 时无法按预期工作,如下所示:

from PyQt4 import QtGui, QtCore

class Window(QtGui.QWidget):
    def __init__(self):
        QtGui.QWidget.__init__(self)
        self.graphicsView = QtGui.QGraphicsView(self)

        self.graphicsView.setMouseTracking(True)
        self.graphicsView.installEventFilter(self)

        layout = QtGui.QVBoxLayout(self)
        layout.addWidget(self.graphicsView)


    def eventFilter(self, source, event):
        if (event.type() == QtCore.QEvent.MouseMove and
            source is self.graphicsView):
            pos = event.pos()
            print('mouse move: (%d, %d)' % (pos.x(), pos.y()))
        return QtGui.QWidget.eventFilter(self, source, event)

if __name__ == '__main__':
    import sys
    app = QtGui.QApplication(sys.argv)
    window = Window()
    window.show()
    window.resize(200, 100)
    sys.exit(app.exec_())

具体来说,似乎只有当我的光标移动越过 QGraphicsView 的边界(黑线)时,事件才会被捕获。

谁能告诉我为什么,有没有更好的解决方案?

对于某些小部件,您需要改用其视口:

    self.graphicsView.viewport().installEventFilter(self)
    ...

def eventFilter(self, source, event):
    if (event.type() == QtCore.QEvent.MouseMove and
        source is self.graphicsView.viewport()):
    ...

另一种方法是直接覆盖 QGraphicsViewmouseMoveEvent(event)

示例:

from PySide import QtGui

class MyGraphicsView(QtGui.QGraphicsView):

    def __init__(self, parent):
        QtGui.QGraphicsView.__init__(self, parent)
        self.setMouseTracking(True)

    def mouseMoveEvent(self, event):
        print('mouseMoveEvent: pos {}'.format(event.pos()))

class Window(QtGui.QWidget):
    def __init__(self):
        QtGui.QWidget.__init__(self)
        self.graphicsView = MyGraphicsView(self)

        layout = QtGui.QVBoxLayout(self)
        layout.addWidget(self.graphicsView)

app = QtGui.QApplication([])
window = Window()
window.show()
window.resize(200, 100)
app.exec_()