2

Consider this extremely simple example in which you can drag a square around a QGraphicsScene (using PyQt, C++ users read self as this)

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

When you click the mouse in the scene you should see a print statement telling you that you clicked either on the square or on nothing (ie. None). This works if you just start the program and click on the square.

Now drag the square away from the upper left corner and click on it again. This time itemAt() return None even when you click on the square.

What's going on?

DanielSank
  • 3,303
  • 3
  • 24
  • 42
  • Check if sceneBoundingRect() on the item returns a sensible value – Frank Osterfeld Oct 21 '13 at 05:32
  • The result of calling sceneBoundingRect() on the Square instance yields a sensible result. However, doing this I realized that the failure described in my original post happens whenever the Square's position is different from (0,0). Is this some funny business having to do with the Scene not getting the Square because the square is outside the scene's bounding rect? This would surprise me because I made the scene 300x300... – DanielSank Oct 21 '13 at 06:04

1 Answers1

6

The answer seems to be that I should have used self.itemAt(e.scenePos()) instead of self.itemAt(e.pos()). I found this in this SO question.

I note here that the reason I've been having trouble finding information on this issue is that moving QGraphicsItems around in a QGraphicsScene is not what Qt calls "drag and drop". To search for information on this topic you want to search for things like "move QGraphicsItem".

Community
  • 1
  • 1
DanielSank
  • 3,303
  • 3
  • 24
  • 42