[PyKDE] PyQt4 problems with underlying C/C++ objects [weird]

Krystian Samp samp.krystian at gmail.com
Tue Nov 21 14:57:47 GMT 2006


Hi,
thanks for the answer. When I commented the line which adds MyItem2 to the
scene the effect was the same - the underlying C/C++ object was destructed.
It is weird but I found some interesting notes on this problem:
http://www.nanoengineer-1.net/mediawiki/index.php?title=Qt_4_mysteries#One_mystery_solved

It seems that when you create an item the python object holds a reference to
it. However, if you assign that item to a hierarchy of items (for instance
using setParentItem()) the python object loses (or you can say hands over)
the reference. This reference still exists in the C/C++ level in the
hierarchy but only there. So If you stop referencing to the parent of the
item then the item itself will be destroyed as well. This is weird since you
still have a python object representing the item but as I said it handed
over the reference to the C/C++ layer. This is my observation and I think
it's not a good behavior of PyQt since you actually have to think about
C/C++ and the principle I've described.

so for the above code snippet it is sufficient to detach children items from
the parent before deleting the parent.

any comments? your observations?

best regards,
Krystian

2006/11/21, Phil Thompson <phil at riverbankcomputing.co.uk>:
>
> On Sunday 19 November 2006 10:18 pm, Krystian Samp wrote:
> > Hi all,
> >
> > I've got the following error:
> >
> > Traceback (most recent call last):
> >   File "test2.py", line 47, in mousePressEvent
> >     item = MyItem2(self.options)
> >   File "test2.py", line 10, in __init__
> >     i.setParentItem(self)
> > RuntimeError: underlying C/C++ object has been deleted
> >
> > for this code (I've tried to make it as short as possible):
> >
> > import sys
> > from PyQt4 import QtGui, QtCore
> >
> > class MyItem2(QtGui.QGraphicsItem):
> >     def __init__(self, items):
> >         QtGui.QGraphicsItem.__init__(self)
> >
> >         self.items = items
> >         for i in self.items:
> >             i.setParentItem(self)
> >
> >     def paint(self, painter, option, widget):
> >         painter.drawEllipse(0, 0, 10, 10)
> >
> >     def boundingRect(self):
> >         return QtCore.QRectF(0, 0, 20, 20)
> >
> >
> > class MyItem1(QtGui.QGraphicsItem):
> >     def __init__(self):
> >         QtGui.QGraphicsItem.__init__(self)
> >
> >     def paint(self, painter, option, widget):
> >         painter.drawEllipse(0, 0, 20, 20)
> >
> >     def boundingRect(self):
> >         return QtCore.QRectF(0, 0, 20, 20)
> >
> >
> > class MyItem(QtGui.QGraphicsItem):
> >     def __init__(self, options):
> >         QtGui.QGraphicsItem.__init__(self)
> >
> >         self.options = options
> >         self.activated = False
> >         self.items = []
> >
> >     def paint(self, painter, option, widget):
> >         pass
> >
> >     def boundingRect(self):
> >         return QtCore.QRectF(-100, -100, 200, 200)
> >
> >     def mousePressEvent(self, event):
> >         self.activated = not self.activated
> >         if self.activated:
> >             item = MyItem2(self.options)
> >             self.scene().addItem(item)
> >             self.items.append(item)
> >             item.setParentItem(self)
> >         if not self.activated:
> >             for i in self.items:
> >                 i.setParentItem(None)
> >                 self.scene().removeItem(i)
> >             self.items = []
> >
> > class MyView(QtGui.QGraphicsView):
> >     def __init__(self):
> >         QtGui.QGraphicsView.__init__(self)
> >
> >         self.scene = QtGui.QGraphicsScene()
> >
> >         self.items = [MyItem1(), MyItem1(), MyItem1()]
> >         self.item = MyItem(self.items)
> >
> >         self.scene.addItem(self.item)
> >         self.setScene(self.scene)
> >
> > # main program
> > app = QtGui.QApplication(sys.argv)
> > view = MyView()
> > view.show()
> >
> > sys.exit(app.exec_())
> >
> > After running it, click several times on the 'canvas' to see the error.
> > It is strange. The error concerns objects which I hold in MyItem.objects.
> I
> > do not understand why the underlying objects are lost. Can anyone
> explain
> > me that?
> > Moreover if I comment the line 'self.items = []' then there is no such
> > error. Is it possible that this assignment destroys C/C++ objects under
> the
> > curtain? Hard to believe.
>
> You are adding MyItem2 to the scene and setting its parent to MyItem. My
> understanding is that you do one or the other. If I'm wrong then there is
> probably a bug in the ownership transfer flags.
>
> Phil
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.riverbankcomputing.com/pipermail/pyqt/attachments/20061121/0de4364e/attachment.html


More information about the PyQt mailing list