【问题标题】:How to get cursor click position in QGraphicsItem coordinate system?如何在 QGraphicsItem 坐标系中获取光标单击位置?
【发布时间】:2019-05-06 17:06:33
【问题描述】:

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

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

【问题讨论】:

    标签: python python-3.x pyqt pyqt5 qgraphicsview


    【解决方案1】:

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

    - 覆盖 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_())
    

    【讨论】:

    • 对于一个普遍的问题有很多解决方案,解决方案取决于 mousePressEvent 覆盖:QGraphicsView、QGraphicsScene 或 QGraphicsItem。
    • 在我的情况下有 QGraphicsView 覆盖。
    • @TarasMykhalchuk 我将为未来的读者发布 3 种方法 :-)
    • 是的,你是对的。从现在开始,这个问题可以被认为是永远关闭了!
    猜你喜欢
    • 2020-02-08
    • 2023-01-30
    • 2017-08-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-04
    相关资源
    最近更新 更多