[PyKDE] PyQt4 Questions
Phil Thompson
phil at riverbankcomputing.co.uk
Mon Mar 20 09:47:15 GMT 2006
On Saturday 18 March 2006 4:11 pm, Detlev Offenbach wrote:
> Am Samstag, 18. März 2006 16:29 schrieb Giovanni Bajo:
> > Detlev Offenbach <detlev at die-offenbachs.de> wrote:
> > > I have a dialog, that creates a new dialog and shows it. The code is
> > > like
> > >
> > > self.dlg = MyDialog(self)
> > > dlg.show()
> >
> > MyDialog is a QObject, and it is constructed as child of self. Its
> > lifetime becomes bound to the lifetime of "self", pretty much like every
> > other child of self (including labels, buttons, etc.).
> >
> > > This code is part of a slot. Whenever this code is hit, a new dialog is
> > > created with destroying the old one. I thought, that the garbage
>
> Typo: created without destroying ...
>
> > > collector should take care of deleting the old one.
> >
> > No, because like any other QObject, its lifetime is bound to its parent,
> > *irrespective* of the lifetime of the Python object (which can be
> > destroyed and recreated on demand). Think of how many widgets you
> > (probably) create to compose a dialog and for which you do *not* keep a
> > Python reference.
>
> In the meantime I did some more tests. I changed the QDialog derived dialog
> to a QWidget derived one and now it get deleted by the garbage collector,
> when I create a new instance. It seems, that the C++ QDialog gets detached
> from its Python proxy.
>
> > > Same thing happens with nonmodal dialogs spawned from the QMainWidget.
> >
> > When
> >
> > > closing the application, I have to close every single dialog, that was
> > > displayed via the show() method, individually.
> >
> > The point is that PyQt *specifically* implements a workaround for QDialog
> > and QPopupMenu when used as *modal* dialogs. If you run the exec_loop()
> > method (and thus request modal behaviour), their lifetime semantic is
> > explicitally changed and becomes bound to the *Python* reference. This
> > allows to write Python code to use modal dialogs which works
> > "out-of-the-box".
> >
> > For modeless dialogs, you're out of luck. There are at least a couple of
> > ways to do what you want:
> >
> > * Explicitally delete the widget before constructing the new one. There
> > is no equivalent of "delete dlg" in Python, so the common way is to call
> > the deleteLater() method. This is usually enough. Notice that you can
> > force the deleteLater() message to be immediately processed by doing:
> > qApp.sendPostedEvents(widget, QEvent.DeferredDelete). Usually you don't
> > need this, though, and waiting till the next event loop is good enough.
>
> It worked ok in PyQt3 but shows the weird (at least for me) behavior for
> PyQt4. Therefore I suspect something wrong with PyQt4 and QDialog.
Can you send me your test case. The PyQt3 and PyQt4 code to handle this is
identical.
Phil
More information about the PyQt
mailing list