[PyKDE] Properly deleting objects from a QWidgetStack

Phil Thompson phil at riverbankcomputing.co.uk
Mon Jul 28 10:30:00 BST 2003


On Sunday 27 July 2003 10:34 pm, Jacob M. Burbach wrote:
> On Sunday 27 July 2003 05:04 am, Phil Thompson wrote:
> > On Saturday 26 July 2003 9:25 pm, Jacob M. Burbach wrote:
> > > On Saturday 26 July 2003 03:22 pm, Jacob M. Burbach wrote:
> > > > What is the proper way to remove and destroy an object from a
> > > > QWidgetStack?
> > > >
> > > > I tried:
> > > > 	object = widgetStack.widget( objectId )
> > > > 	widgetStack.removeWidget( object )
> > > > 	del object
> > > >
> > > > However it doesn't seem to call the destructor of that object,
> > > > causing a memory leak. What is the proper way to do this to make sure
> > > > the object really gets destroyed?
> > > >
> > > >
> > > > _______________________________________________
> > > > PyKDE mailing list    PyKDE at mats.imk.fraunhofer.de
> > > > http://mats.imk.fraunhofer.de/mailman/listinfo/pykde
> > >
> > > Update, after doing a quick check, I see I have to call
> > > QWidgetStack.removeChild to actually decrease the reference count
> > >
> > > Example:
> > > 	object = widgetStack.widget( objectId )
> > >   	widgetStack.removeWidget( object )
> > > 	widgerStack.removeChild(object)
> > > 	print sys.getrefcount(object)
> > >  	del object
> > >
> > > Which says it has 2 references, one would be the object variable, so
> > > apparently I have an extra reference laying around somewhere...
> >
> > When you add a widget to a QWidgetStack ownership is transfered to C++
> > because the widget is re-parented and so it's C++ dtor will be called as
> > a consequence of the QWidgetStack's dtor being called. When ownership is
> > transfered, the reference count is incremented - so that, if ownership is
> > transfered back, the original Python object (including it's specific
> > type) is returned.
> >
> > You might expect ownership of the widget to be transfered back to Python
> > when you call removeWidget(). It isn't because the widget isn't removed
> > from the QWidgetStack's children. Another option, other that
> > removeChild(), would be to reparent() the child and give it a new parent
> > of None.
> >
> > Phil
>
> Unfortunately calling either removeChild, or using reparent with a None
> parent, both caused my app to eventually crash when exiting. Any idea what
> may cause the crash? The only thing I can think of is maybe python wasn't
> aware the C++ object had been destroyed, and eventually tried to call its
> destructor when the app exited?

But what's causing the C++ object to be destroyed?

> I did find a solution in an old post by Jim Bublitz;
>
> >Originally posted by Jim Bublitz
> >  def removeWidget (self, w) #w is a QWidget/QObject descendant
> >      dummy = QWidget ()
> >      w.reparent (dummy, QPoint (0, 0))
> >      # when dummy goes out of scope, it gets garbage collected
> >      # along with all of it's children (and the corresponding
> >      # C++ objects get destroyed as well)
> >
> >The way Qt handles the above is different than the way
> >'removeChild' followed by 'del w' would work.
>
> So now in my app I retrieve the widget from the stack, then send it to a
> function like above to get destroyed. This works good, and my app doesn't
> crash.
>
> It may be worth noting, this is a KDE app, using PyQt-3.5 with PyKDE, and
> the widgets stored in the stack are from KDE.

If you can produce a small, complete, PyQt only example that demonstrates the 
problem, I'll have a proper look at it.

Phil




More information about the PyQt mailing list