PyQt5:GraphicsScene的所有项目的坐标均为0.0

问题描述

我使用以下source并对其进行了一些修改,以得到以下迷你示例:

import sys
from PyQt5 import QtCore,QtWidgets

class GraphicsScene(QtWidgets.QGraphicsScene):
    def __init__(self):
        super(GraphicsScene,self).__init__()
        self.setSceneRect(0,600,400)


    def mousepressEvent(self,event):
        if event.buttons() == QtCore.Qt.LeftButton:
            x = event.scenePos().x()
            y = event.scenePos().y()
            self.addRect(x,y,100,100)
        elif event.buttons() == QtCore.Qt.RightButton:
            for elem in self.items():
                print(elem.x())
        super(GraphicsScene,self).mousepressEvent(event)

if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    scene = GraphicsScene()
    w = QtWidgets.QGraphicsView(scene)
    w.resize(610,410)
    w.show()
    sys.exit(app.exec_())

想法是,通过单击鼠标左键来创建新矩形(这已经起作用),然后通过单击鼠标右键来删除最近的矩形。我知道如何找到最近的矩形,但是为此,我需要现有矩形的坐标。如果将新矩形添加到场景中,请执行以下操作:

self.addRect(x,100)

但是如果我遍历场景中的所有元素,并尝试使用以下方法获取元素的x坐标:

    for elem in self.items():
        print(elem.x())
        print(elem.pos().x())
        print(elem.scenePos().x())

则所有打印输出均为零。我已经看过docu,但是据我所知,我正在做文档建议的事情。你知道我在做什么错吗?


编辑: 当然,我可以将所有坐标保存在其他列表中,使用该列表中的值计算最近的矩形,使用以下方法删除每个矩形:

    for elem in self.items():
        self.removeItem(elem)

并绘制剩余的矩形。但是,我希望有一个更干净的版本。 :)

解决方法

作为documentation explains

请注意,物品的几何形状在物品坐标中提供,并且其位置被初始化为(0,0)。例如,如果添加了QRect(50,50,100,100),则其左上角将相对于项目坐标系中的原点位于(50,50)。

所以有两种选择:

  • 在位置(0,0)处添加具有指定大小的矩形,然后将其移动到所需位置:
    rectItem = self.addRect(0,100,100)
    rectItem.setPos(x,y)
  • 使用addRect中的坐标并基于矩形的左上角获取实际位置:
    for elem in self.items():
        pos = elem.pos()
        if isinstance(elem,QtWidgets.QGraphicsRectItem):
            pos += elem.rect().topLeft()