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

4

我有一个带有QGraphicsItemQGraphicsScene。假设我点击了地图图片(QGraphicsItem),在其中绘制了绿色圆。如何以此QGraphicsItem而不是QGraphicsScene坐标系来获取点击位置。

road_map

附言:请不要使用鼠标事件处理编写代码,只需正确映射点击位置的方法即可。提前致谢。

1个回答

6

这个想法是将相对于场景的坐标转换为相对于物品的坐标。

- 在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_())

1
对于一般问题,有许多解决方案,解决方案取决于mousePressEvent被重写的位置:QGraphicsView、QGraphicsScene或QGraphicsItem。 - eyllanesc
在我的情况下,存在QGraphicsView的覆盖。 - Taras Mykhalchuk
@TarasMykhalchuk 我会为未来的读者发布这3种方法 :-) - eyllanesc
是的,你说得对。从现在开始,这个问题可以被视为永久关闭了! - Taras Mykhalchuk

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接