On Saturday 14 February 2004 07:49, Stefan Seefeld wrote:
> Phil Thompson wrote:
> > On Saturday 14 February 2004 04:46, Stefan Seefeld wrote:
> >>hi there,
> >>
> >>I'm experimenting with pyqt and I'm running in
> >>some strange behavior.
> >>The examples3/canvas/canvas.py demo contains
> >>the following lines:
> >>
> >> def newView(self):
> >> self.m=Main(self.canvas,None,"new windiw",Qt.WDestructiveClose)
> >> qApp.setMainWidget(self.m)
> >> self.m.show()
> >> qApp.setMainWidget(None)
> >>
> >>What I'm wondering about is the reason for the 'Main' instance to
> >>be stored in an attribute. In fact, if I replace 'self.m' by 'm'
> >>the applet doesn't work any more, i.e. as soon as I create the
> >>second view the first will be destructed. What's the reason for
> >>this ? It appears the ref count for the view drops to zero so
> >>it gets destroyed...
> >
> > Correct, 'm' is garbage collected when newView() returns, 'self.m' is
> > garbage collected when 'self' is garbage collected.
> >
> >>But in the above, it would seem the second call to 'newView' would
> >>free the first view, and thus destroy it, too. That, however, is
> >>not the case.
> >
> > But the second call to newView() has a different self.
>
> How so ? Is it not the 'self' of the view containing the menu I clicked on
> ? A little try showed the same value for 'id(self)' if I call 'newView'
> multiple times.
If you repeatedly click on New View in the same view then previous views get
garbage collected.
If you click on New View in a new view then another view is created.
This is consistent with the code, but is a bug because the code is a Python
translation of the original C++ and doesn't take full account of the garbage
collection issue.
The attached patch fixes the behaviour.
> I guess I need to understand the 'setMainWidget' trick in order to see
> why it works. 'm' is set to be the main widget, then it is mapped, then
> 'None' is set to be the main widget. What does this call do ? (I note
> it's also in the C++ example, so it probably isn't related to python's
> ref counting).
No, it's nothing to do with the reference counting.
Phil
--- canvas.py.orig 2004-02-14 07:21:04.000000000 +0000
+++ canvas.py 2004-02-14 07:15:49.000000000 +0000
@@ -13,6 +13,7 @@
logo_fn = QString.null
logoimg = []
bouncy_logo = None
+views = []
class ImageItem(QCanvasRectangle):
@@ -278,10 +279,11 @@
self.addLogo()
def newView(self):
- self.m=Main(self.canvas,None,"new windiw",Qt.WDestructiveClose)
- qApp.setMainWidget(self.m)
- self.m.show()
+ m=Main(self.canvas,None,"new windiw",Qt.WDestructiveClose)
+ qApp.setMainWidget(m)
+ m.show()
qApp.setMainWidget(None)
+ views.append(m)
def clear(self):
self.editor.clear()
@@ -612,5 +614,6 @@
# We need to explicitly delete the canvas now (and, therefore, the main
# window beforehand) to make sure that the sprite logo doesn't get garbage
# collected first.
+ views = []
del m
del canvas