Am Samstag, 18. März 2006 16:29 schrieb Giovanni Bajo: > Detlev Offenbach <[EMAIL PROTECTED]> 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. > > * Tell SIP that you want the lifetime of the dialog to be bound to the > Python object. This is spelled: "sip.transferback(self.dlg)". You need to > import sip, of course. This is *exactly* what PyQt does when you call the > exec_loop() method in QDialog and QPopupMenu. > > > Additionally I have seen this strange behavior. If I create the dialog > > above > > > with self as a parent, the dialog containing the slot is put behind all > > other windows. > > > > Another observation is, that the newly generated dialog (using the above > > code) is put centered on top of the generating dialog. I expected the > > window > > > manager to take care of the placement. > > > > The last observation is, that the generating dialog is always behind the > > generated dialog. I cannot bring it into the foreground. > > I see these behaviours with Qt under Windows, but I didn't bother > investigated, and I blamed it on Windows' window manager. I don't think > PyQt has anything to do with either, though. Maybe there is a workaround > for the latter you mentioned (in the WFlags) but I don't recall. Detlev -- Detlev Offenbach [EMAIL PROTECTED] _______________________________________________ PyKDE mailing list [email protected] http://mats.imk.fraunhofer.de/mailman/listinfo/pykde
