E.G. Cortes
E.G. Cortes

Reputation: 75

Clear a QGraphicsScene from an event of one of the items

I have a QGraphicsScene with many QGraphicsItem. Some items have buttons that clear and repaint the scene.

The problem is that the clear() method deletes the QButton (and its associated data structures) in the middle of a method call that uses those very data structures. Then, immediately after clear() returns, the calling method tries to access the now-deleted data (because it wasn't expecting to be deleted in the middle of its routine), and bang -- a crash. From here.

I found the solution for C ++ here, however I am using PySide and could not use the same solution for python.

Follow my code:

class GraphicsComponentButtonItem(QtGui.QGraphicsItem):

    def __init__(self, x, y, update_out):
        super(GraphicsComponentButtonItem, self).__init__()

        self.x = x
        self.y = y
        self.update_out = update_out

        self.setPos(x, y)

        self.createButton()
        self.proxy = QtGui.QGraphicsProxyWidget(self)
        self.proxy.setWidget(self.button)

    def boundingRect(self):
        return QtCore.QRectF(self.x, self.y, self.button.width(), self.button.height())

    def paint(self, painter, option, widget):
        # Paint same stuffs

    def createButton(self):
        self.button = QtGui.QPushButton()
        self.button.setText('Clear')
        self.button.clicked.connect(self.action_press)

    def action_press(self):
        # Run some things
        self.update_out()


class QGraphicsViewButtons(QtGui.QGraphicsView):

    def __init__(self, scene, parent=None):
        QtGui.QGraphicsView.__init__(self, parent)
        self.scene = scene

    # It's called outside
    def updateScene(self):
        self.scene.clear()
        self.scene.addItem(GraphicsComponentButtonItem(0, 0, self.updateScene))
        self.scene.addItem(GraphicsComponentButtonItem(0, 50, self.updateScene))
        self.scene.addItem(GraphicsComponentButtonItem(0, 100, self.updateScene))

Upvotes: 1

Views: 1394

Answers (1)

eyllanesc
eyllanesc

Reputation: 243897

the conversion of the following C++ code:

QObject::connect(button, SIGNAL(clicked()), scene, SLOT(clear()), Qt::QueuedConnection);

to python is:

self.button.clicked.connect(self.scene().clear, QtCore.Qt.QueuedConnection)

Upvotes: 1

Related Questions