> Phil Thompson <[EMAIL PROTECTED]> 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    [email protected]
http://mats.imk.fraunhofer.de/mailman/listinfo/pykde

Reply via email to