在 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() 方法没有找到正方形。
- 解决方案
这个问题的原因是,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_())