在 PyQt 中无法使用 itemAt() 找到 QGraphicsItem 的原因和解决方法

在 PyQt 中,使用 itemAt() 方法可以获取指定位置的 QGraphicsItem 对象。然而,在某些情况下,itemAt() 可能会返回 None,即使你点击了 QGraphicsItem。

例如,在下面的代码中,我们创建了一个简单的图形场景,其中包含一个正方形。当用户单击场景时,我们使用 itemAt() 方法获取用户单击的位置处的 QGraphicsItem 对象,并将其打印到控制台。

import sys
from PyQt4 import QtGui, QtCore

class MainWindowUi(QtGui.QMainWindow):
    def __init__(self):
        QtGui.QMainWindow.__init__(self)
        self.scene = Scene(0, 0, 300, 300, self)
        self.view = QtGui.QGraphicsView()
        self.setCentralWidget(self.view)
        self.view.setScene(self.scene)
        self.scene.addItem(Square(0,0,50,50))

class Scene(QtGui.QGraphicsScene):

    def mousePressEvent(self, e):
        self.currentItem = self.itemAt(e.pos())
        print (self.currentItem)
        QtGui.QGraphicsScene.mousePressEvent(self, e)

class Square(QtGui.QGraphicsRectItem):
    def __init__(self, *args):
        QtGui.QGraphicsRectItem.__init__(self, *args)
        self.setFlag(QtGui.QGraphicsItem.ItemIsMovable, True)
        self.setFlag(QtGui.QGraphicsItem.ItemIsSelectable, True)

if __name__ == '__main__':
    app = QtGui.QApplication(sys.argv)
    win = MainWindowUi()
    win.show()
    sys.exit(app.exec_())

如果我们运行这段代码,然后单击正方形,我们会看到以下输出:

<PyQt4.QtGui.QGraphicsRectItem object at 0x7f1a34510db0>

这表明 itemAt() 方法成功地找到了正方形。

然而,如果我们现在将正方形拖离左上角,然后再次单击它,我们会看到以下输出:

None

这表明 itemAt() 方法没有找到正方形。

  1. 解决方案

这个问题的原因是,itemAt() 方法使用场景中的本地坐标来查找 QGraphicsItem 对象。这意味着,如果你将 QGraphicsItem 对象移动到场景中的不同位置,itemAt() 方法将无法再找到它。

为了解决这个问题,我们可以使用 itemAt(e.scenePos()) 方法来查找 QGraphicsItem 对象。itemAt(e.scenePos()) 方法使用场景中的全局坐标来查找 QGraphicsItem 对象,因此它不受 QGraphicsItem 对象的位置影响。

将上面的代码中的

self.currentItem = self.itemAt(e.pos())

替换为

self.currentItem = self.itemAt(e.scenePos())

然后重新运行代码,你会发现 itemAt() 方法现在可以找到正方形,无论它位于场景中的哪个位置。

以下是修改后的代码:

import sys
from PyQt4 import QtGui, QtCore

class MainWindowUi(QtGui.QMainWindow):
    def __init__(self):
        QtGui.QMainWindow.__init__(self)
        self.scene = Scene(0, 0, 300, 300, self)
        self.view = QtGui.QGraphicsView()
        self.setCentralWidget(self.view)
        self.view.setScene(self.scene)
        self.scene.addItem(Square(0,0,50,50))

class Scene(QtGui.QGraphicsScene):

    def mousePressEvent(self, e):
        self.currentItem = self.itemAt(e.scenePos())
        print (self.currentItem)
        QtGui.QGraphicsScene.mousePressEvent(self, e)

class Square(QtGui.QGraphicsRectItem):
    def __init__(self, *args):
        QtGui.QGraphicsRectItem.__init__(self, *args)
        self.setFlag(QtGui.QGraphicsItem.ItemIsMovable, True)
        self.setFlag(QtGui.QGraphicsItem.ItemIsSelectable, True)

if __name__ == '__main__':
    app = QtGui.QApplication(sys.argv)
    win = MainWindowUi()
    win.show()
    sys.exit(app.exec_())
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值