QGraphicsProxyWidget messes up mouse cursor changes

Viewed 114

I have a QGraphicsView where I do various mouse operations and while doing mouse operations I change mouse cursor to give user visual clues.

I recently put some QWidgets onto my scene which automatically creates QGraphicsProxyWidget objects. And after putting these widgets I started having problems with my mouse cursor changes. I can change mouse cursor until I hover over a QGraphicsProxyWidget item. After that, my mouse cursor changes stop taking effect.

I created a minimal example in PySide2:

import sys

from PySide2.QtGui import QMouseEvent, Qt
from PySide2.QtWidgets import QApplication, QLabel, QGraphicsView, QGraphicsScene


class CustomGraphicsView(QGraphicsView):
    def mousePressEvent(self, event: QMouseEvent):
        super().mousePressEvent(event)

        self.setCursor(Qt.ClosedHandCursor)
        event.accept()

    def mouseReleaseEvent(self, event: QMouseEvent):
        super().mouseReleaseEvent(event)

        self.setCursor(Qt.ArrowCursor)
        event.accept()


if __name__ == "__main__":
    app = QApplication(sys.argv)
    graphics_view = CustomGraphicsView()
    scene = QGraphicsScene(0, 0, 1000, 1000)
    graphics_view.setScene(scene)

    label = QLabel("Hello World")
    label_font = label.font()
    label_font.setPointSize(50)
    label.setFont(label_font)

    label_proxy = scene.addWidget(label)
    label_proxy.setPos(400, 450)

    graphics_view.show()
    app.exec_()

To reproduce: first, click on anywhere in the scene without hovering your mouse over the "Hello World" text. You will see mouse cursor changing into a closed hand. Then hover your mouse over "Hello World" text and try again clicking anywhere on scene. You will see that the cursor is not changing anymore.

I am not sure if this is an expected behavior or bug. What might be the reason for this behavior?

System

OS: Windows 10 20H2

Python 3.8.6 64-bit

PySide2 5.15.2

1 Answers

Disclaimer: Still investigating the cause of that behavior so at the time of writing this answer I will only give the solution. But it seems is that the propagation of the events is not handled correctly by the QGraphicsProxyWidget. See this bug for more information.

Instead of setting the cursor in the QGraphicsView it should be set in the viewport.

class CustomGraphicsView(QGraphicsView):
    def mousePressEvent(self, event: QMouseEvent):
        super().mousePressEvent(event)
        self.viewport().setCursor(Qt.ClosedHandCursor)
        event.accept()

    def mouseReleaseEvent(self, event: QMouseEvent):
        super().mouseReleaseEvent(event)
        self.viewport().unsetCursor()
        event.accept()
Related