如何获取QGraphicsItem坐标系中的光标点击位置?

How to get cursor click position in QGraphicsItem coordinate system?

我有一个 QGraphicsScene 添加了 QGraphicsItem。假设我单击了绘制绿色圆圈的地图图像 (QGraphicsItem)。如何根据此 QGraphicsItem 而不是 QGraphicsScene 坐标系获取点击位置。

P.S。请不要编写带有鼠标事件处理的代码。如何正确映射点击位置。提前致谢。

想法是将相对于场景的坐标转换为相对于项目的坐标。

- 覆盖 QGraphicsScene 中的 mousePressEvent:

使用 QGraphicsItem 的 mapFromScene() 方法:

from PyQt5 import QtCore, QtGui, QtWidgets
import random

class Scene(QtWidgets.QGraphicsScene):
    def __init__(self, parent=None):
        super(Scene, self).__init__(parent)
        pixmap = QtGui.QPixmap(100, 100)
        pixmap.fill(QtCore.Qt.red)

        self.pixmap_item = self.addPixmap(pixmap)
        # random position
        self.pixmap_item.setPos(*random.sample(range(-100, 100), 2))


    def mousePressEvent(self, event):
        items = self.items(event.scenePos())
        for item in items:
            if item is self.pixmap_item:
                print(item.mapFromScene(event.scenePos()))
        super(Scene, self).mousePressEvent(event)

if __name__ == '__main__':
    import sys
    app = QtWidgets.QApplication(sys.argv)
    scene = Scene()
    w = QtWidgets.QGraphicsView(scene)
    w.resize(640, 480)
    w.show()
    sys.exit(app.exec_())

- 在 QGraphicsView 中覆盖 mousePressEvent:

使用 QGraphicsItem 的 mapFromScene() 方法和 mapToScene():

from PyQt5 import QtCore, QtGui, QtWidgets
import random

class View(QtWidgets.QGraphicsView):
    def __init__(self, parent=None):
        super(View, self).__init__(QtWidgets.QGraphicsScene(), parent)
        pixmap = QtGui.QPixmap(100, 100)
        pixmap.fill(QtCore.Qt.red)

        self.pixmap_item = self.scene().addPixmap(pixmap)
        # random position
        self.pixmap_item.setPos(*random.sample(range(-100, 100), 2))


    def mousePressEvent(self, event):
        items = self.items(event.pos())
        for item in items:
            if item is self.pixmap_item:
                print(item.mapFromScene(self.mapToScene(event.pos())))
        super(View, self).mousePressEvent(event)

if __name__ == '__main__':
    import sys
    app = QtWidgets.QApplication(sys.argv)
    w = View()
    w.resize(640, 480)
    w.show()
    sys.exit(app.exec_())

- 覆盖 QGraphicsItem 的 mousePressEvent:

from PyQt5 import QtCore, QtGui, QtWidgets
import random

class PixmapItem(QtWidgets.QGraphicsPixmapItem):
    def mousePressEvent(self, event):
        print(event.pos())
        super(PixmapItem, self).mousePressEvent(event)

if __name__ == '__main__':
    import sys
    app = QtWidgets.QApplication(sys.argv)
    scene = QtWidgets.QGraphicsScene()
    w = QtWidgets.QGraphicsView(scene)
    pixmap = QtGui.QPixmap(100, 100)
    pixmap.fill(QtCore.Qt.red)
    item = PixmapItem(pixmap)
    scene.addItem(item)
    item.setPos(*random.sample(range(-100, 100), 2))
    w.resize(640, 480)
    w.show()
    sys.exit(app.exec_())