Deleting an item from a scene

3.1k views Asked by At

I currently am having an issue with a delete button I created that is linked to a QGraphicsScene class. The button is created in the Window class not the MyView class. I am trying to have the user be able to delete marks that were made on a scene but right now it is only deleting the last ellipse item I create and nothing else. The error that pops up usually says that the other objects you are trying to delete are in a different scene. Also the location of the circle object that wants to be deleted is important. So if the user has the cursor over a particular circle that circle item should delete and nothing else. Here's my code:

import sys
from PyQt4 import QtGui, QtCore
#this sets the scene for drawing and the microscope image
class MyView(QtGui.QGraphicsView):
    def __init__(self,window):
        QtGui.QGraphicsView.__init__(self)
        self.window = window
        self.scene = QtGui.QGraphicsScene(self)
        self.item = QtGui.QGraphicsRectItem(400, 400, 400, 400)
        self.scene.addItem(self.item)
        self.setScene(self.scene)
    def paintMarkers(self,event):
        ##self.cursor = QtGui.QCursor()
        #self.cursor.setShape(2)
        p = self.mapToScene(event.x(),event.y())
        self.circleItem = QtGui.QGraphicsEllipseItem(p.x(),p.y(),5,5)
        self.scene.addItem(self.circleItem)
        self.circleItem.setPen(QtGui.QPen(QtCore.Qt.red, 1.5))
        #self.setScene(self.scene)
    def deleteMarkers(self):
        self.scene.removeItem(self.circleItem)
        #print "Hello world"
    #def mousePressEvent(self,QMouseEvent):
        #self.paintMarkers()
    def mousePressEvent(self,event):
        if self.window.btnPaintDot.isChecked():
            self.paintMarkers(event)
        if self.window.btnDeleteMarks.isChecked():
            self.deleteMarkers()
        return QtGui.QGraphicsView.mousePressEvent(self,event)




class Window(QtGui.QMainWindow):
        def __init__(self):
            #This initializes the main window or form
            super(Window,self).__init__()
            self.setGeometry(50,50,1000,1000)
            self.setWindowTitle("Pre-Alignment system")

            self.view = MyView()
            self.setCentralWidget(self.view)
    #makes deletemarks button checked when pressed
        def paintDeleteMarks(self):
            if self.btnDeleteMarks.isChecked():
                self.btnPaintDot.setChecked(False)
                self.btnPaintPolygon.setChecked(False)
                self.btnPaintPolygon.setChecked(False)
                self.btnDeleteMarks.setChecked(True)
            else:
                self.btnDeleteMarks.setChecked(False)

Much thanks please ask questions if my explanation needs more...well explaining.

2

There are 2 answers

1
three_pineapples On BEST ANSWER

If you carefully read over your code, you will see that you are deleting the item stored in self.circleItem. The item stored in that variable is always only the last one created (you overwrite the variable each time you create a new item).

You need to modify your code so that it finds items based on the current x-y coordinate of the mouse event. Use QGraphicsScene.itemAt() to find the item at a particular x-y coordinate (remember to correctly transform the coordinates relative to the scene before looking up the item at that location).

0
MatthewS2494 On

Here is the code that fixed the issue thanks to three_pineapples!

    import sys
from PyQt4 import QtGui, QtCore
#this sets the scene for drawing and the microscope image
class MyView(QtGui.QGraphicsView):
    def __init__(self,window):
        QtGui.QGraphicsView.__init__(self)
        self.window = window
        self.scene = QtGui.QGraphicsScene(self)
        self.item = QtGui.QGraphicsRectItem(400, 400, 400, 400)
        self.scene.addItem(self.item)
        self.setScene(self.scene)
    def paintMarkers(self,event):
        ##self.cursor = QtGui.QCursor()
        #self.cursor.setShape(2)
        p = self.mapToScene(event.x(),event.y())
        if (p.x() > 400 and p.x() < 800) and (p.y() > 400 and p.y() < 800):
            self.circleItem = QtGui.QGraphicsEllipseItem(p.x(),p.y(),5,5)
        self.scene.addItem(self.circleItem)
        self.circleItem.setPen(QtGui.QPen(QtCore.Qt.red, 1.5))
        #self.setScene(self.scene)
    def deleteMarkers(self,event):
        p = self.mapToScene(event.x(),event.y())
        if self.scene.itemAt(p.x(),p.y()) != self.item:
            self.scene.removeItem(self.scene.itemAt(p.x(),p.y()))
        #print "Hello world"
    #def mousePressEvent(self,QMouseEvent):
        #self.paintMarkers()
    def mousePressEvent(self,event):
        if self.window.btnPaintDot.isChecked():
            self.paintMarkers(event)
        if self.window.btnDeleteMarks.isChecked():
            self.deleteMarkers(event)
        return QtGui.QGraphicsView.mousePressEvent(self,event)