[prev in list] [next in list] [prev in thread] [next in thread]
List: pykde
Subject: Re: [PyKDE] Issue with QDialog and lifetime
From: "Phil Thompson" <phil () riverbankcomputing ! co ! uk>
Date: 2005-07-07 12:45:38
Message-ID: 30636.194.203.13.71.1120740338.squirrel () river-bank ! demon ! co ! uk
[Download RAW message or body]
> Phil Thompson <phil@riverbankcomputing.co.uk> wrote:
>
>>> The problem is that the idiomatic way of using modal dialogs in C++ is
>>> to
>>> create local variables, which gets destroyed when their scope finishes
>>> (when
>>> the function exits). Moreover, the dialogs have to be children of
> whatever
>>> widgets they are modal over (e.g. the main window).
>>>
>>> This has no direct translations in PyQt. If you do:
>>>
>>> def slotWhatever(self):
>>> dlg = MyModalDialog(self)
>>> if dlg.exec_loop() == QDialog.Accepted:
>>> return dlg.data()
>>> return None
>>>
>>> you are leaking "dlg" because its lifetime is bound to its parent. The
>>> current common workaround is something like:
>>>
>>> def slotWhatever(self):
>>> dlg = MyModalDialog(self)
>>> try:
>>> if dlg.exec_loop() == QDialog.Accepted:
>>> return dlg.data()
>>> return None
>>> finally:
>>> dlg.deleteLater()
>>>
>>> which is ugly and error-prone (you have to remember to do it).
>>>
>>> James proposed this solution:
>>>
>>> def slotWhatever(self):
>>> dlg = MyModalDialog(self)
>>> sip.transfer(dlg, 0)
>>> if dlg.exec_loop() == QDialog.Accepted:
>>> return dlg.data()
>>> return None
>>>
>>> and then proposed to hardcode the transfer() call within the
>>> %MethodCode
>>> for
>>> QDialog.exec_loop. I'll remember you that exec_loop is called only for
>>> modal
>>> dialogs, while for modeless dialogs show() is called.
>>
>> I'm uncomfortable with this for two reasons...
>>
>> 1. It's inconsistent behaviour. As there are things you need to be aware
>> of when using PyQt (particularly with regard to ownership) I think it's
>> important to have consistency in those things.
>>
>> 2. It creates the strong possibility of a seg fault for those (existing)
>> applications that don't follow the common idiom.
>
> Yeah, I understand. Better ideas?
1. Either add an optional parameter to exec_loop() which does the transfer
or have exec_loop_and_transfer() (or something less of a mouthful). At
least that way it won't break existing code.
2. Implement sip.destroy() which calls the C++ dtor of its argument. (This
is on the TODO list anyway.)
3. Use sip.transfer().
Either way, I don't think it can be done (to my satisfaction)
transparently. The programmer is going to have to be aware of the issue
and explicitly deal with it.
Phil
_______________________________________________
PyKDE mailing list PyKDE@mats.imk.fraunhofer.de
http://mats.imk.fraunhofer.de/mailman/listinfo/pykde
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic