1
votes

I am writing an application that allows a user to place images on a QGraphicsScene (contained within a QGraphicsView) by clicking on a blank area and then move them about using mousemoveevent. The images are created using a subclassed QGraphicsPixmapItem.

Here's the problem: The very first attempt at moving an item works as expected. However, for all subsequent moves the selected item immediately jumps to the upper left corner of the scene. Here is the code:

import sys
from PySide import QtGui,QtCore

class TestPixmapItem(QtGui.QGraphicsPixmapItem):
    def __init__(self, imagename, position, parent=None):
        QtGui.QGraphicsPixmapItem.__init__(self, parent)

        px = QtGui.QPixmap(imagename)
        self.setPixmap(px)

        self.setFlag(QtGui.QGraphicsItem.ItemIsMovable, True)
        self.setFlag(QtGui.QGraphicsItem.ItemIsSelectable, True)

        # set position
        self.setPos(position.x(),position.y())

    def mouseReleaseEvent(self,e):
        self.setSelected(False)

    def mouseMoveEvent(self, e):
        QtGui.QGraphicsPixmapItem.mouseMoveEvent(self, e)


class GfxScene(QtGui.QGraphicsScene):
    def __init__(self, parent=None):
        #build parent user interface
        super(GfxScene, self).__init__(parent)

    def mousePressEvent(self, e):
        if(self.itemAt(e.scenePos().x(),e.scenePos().y()) == None):
            pixmapItem = TestPixmapItem('test.png',e.scenePos())
            self.addItem(pixmapItem)
        else:
            QtGui.QGraphicsScene.mousePressEvent(self,e); 


class MainForm(QtGui.QMainWindow):
    def __init__(self, parent=None):
        super(MainForm, self).__init__(parent)

        scene = GfxScene(self)
        scene.setSceneRect(QtCore.QRect(0, 0, 800, 800))

        view = QtGui.QGraphicsView()
        view.setScene(scene)
        view.setSceneRect(scene.sceneRect())
        #view.setGeometry(QtCore.QRect(0, 0, 800, 800))
        self.setCentralWidget(view)


def main():
    #This function means this was run directly, not called from another python file.
    app = QtGui.QApplication.instance()
    if app == None:
            app = QtGui.QApplication(sys.argv)
    myapp = MainForm()
    myapp.show()

    sys.exit(app.exec_())


if __name__ == '__main__':
    main() 

Any help would be appreciated!

1

1 Answers

4
votes

You should call the QtGui.QGraphicsPixmapItem.mouseReleaseEvent(self, e) when you override the mouse release event, see : http://goo.gl/ChSYP

import sys
from PySide import QtGui,QtCore

class TestPixmapItem(QtGui.QGraphicsPixmapItem):
    def __init__(self, imagename, position, parent=None):
        QtGui.QGraphicsPixmapItem.__init__(self, parent)

    px = QtGui.QPixmap(imagename)
    self.setPixmap(px)

    self.setFlag(QtGui.QGraphicsItem.ItemIsMovable, True)
    self.setFlag(QtGui.QGraphicsItem.ItemIsSelectable, True)

    # set position
    self.setPos(position.x(),position.y())

def mouseReleaseEvent(self,e):
    self.setSelected(False)
    QtGui.QGraphicsPixmapItem.mouseReleaseEvent(self, e) // here calling the event

def mouseMoveEvent(self, e):
    QtGui.QGraphicsPixmapItem.mouseMoveEvent(self, e)


class GfxScene(QtGui.QGraphicsScene):
    def __init__(self, parent=None):
        #build parent user interface
        super(GfxScene, self).__init__(parent)

def mousePressEvent(self, e):
    if(self.itemAt(e.scenePos().x(),e.scenePos().y()) == None):
        pixmapItem = TestPixmapItem('test.png',e.scenePos())
        self.addItem(pixmapItem)
    else:
        QtGui.QGraphicsScene.mousePressEvent(self,e); 


class MainForm(QtGui.QMainWindow):
    def __init__(self, parent=None):
        super(MainForm, self).__init__(parent)

    scene = GfxScene(self)
    scene.setSceneRect(QtCore.QRect(0, 0, 800, 800))

    view = QtGui.QGraphicsView()
    view.setScene(scene)
    view.setSceneRect(scene.sceneRect())
    #view.setGeometry(QtCore.QRect(0, 0, 800, 800))
    self.setCentralWidget(view)


def main():
    #This function means this was run directly, not called from another python file.
    app = QtGui.QApplication.instance()
    if app == None:
        app = QtGui.QApplication(sys.argv)
    myapp = MainForm()
    myapp.show()

sys.exit(app.exec_())


if __name__ == '__main__':
    main()