[PySide] QObject.destroyed() is not emitted

Christian Tismer tismer at stackless.com
Thu Nov 29 21:10:49 CET 2012


Hi again,

after some thought, I believe I can write a little helper function
that would be added to a class with a wrapper that looks like so
when called:


from pyside_fix import fix_destroy

class MyModel(QAbstractTableModel):

    ...

    @fix_destroy
    def onDestroy(self):
      print('destroyed signal:', self.important)


This function would create such a helper class that allows access
to the dying object (while being a fake class), bind the instance
__dict__ to a function default, turn onDestroy into something different
which still has a fake self with correct attributes etc. etc.
and behaves mostly "right".

This is meant as a helper until PySide gets really fixed.

Should I do that?

cheers -- chris


On 11/29/12 7:57 PM, Christian Tismer wrote:
> Hi,
>
> On 11/29/12 6:37 PM, Stephan Deibel wrote:
>> Alexey Vihorev wrote:
>>> Thanks, nice find, but... I hit the next hurdle trying to go this
>>> way. The signal QObject.destroyed(obj) is passing no arguments
>>> (probably because obj is already destroyed), so my static method has
>>> nothing to work on. Which kind of devaluates the whole idea, IMHO.
>>> And in PyQt4 it*does* pass the object. Even more: in PyQt4 there is
>>> no need for static method approach, as it works perfectly with
>>> instance methods:
>> Yea, you would have to bind the necessary data to the callback like this:
>>
>>    def on_destroy(val1=self.whatever, val2=self.something):
>>      print 'destroyed'
>>    self.destroyed.connect(on_destroy)
> Here is a not really nice hack, but it works, based on Stefan's
> bug tracker code:
>
> The idea is to simply capture the __dict__ of the object and to abuse it
> as the dict of a helper class. This way, although the object goes away,
> it __dict__ survives, and we can work on it after deletion.
>
>
> from PySide.QtCore import QAbstractTableModel
>
> class MyModel(QAbstractTableModel):
>     def __init__(self, *args):
>       super(MyModel, self).__init__(*args)
>       
>       # This one does not work because the instance is destroyed already
>       # so the method call does not happen
>       self.destroyed.connect(self.onDestroy)
>       
>       # This does work because the instance doesn't have to exist anymore
>       def on_destroy():
>         print "destroyed signal: function"
>       self.destroyed.connect(on_destroy)
>       
>       self.important = 42
>       
>     def onDestroy(self):
>       print('destroyed signal: method')
>       
>     def do_something(self):
>       self.important += 1
>
> m = MyModel()
>
> class Helper(object):
>       def __init__(self, inst):
>           self.__dict__ = inst.__dict__
>
> h = Helper(m)
>
> m.do_something()
> m.important
>
> del m
> print(h.important)
>
> print("Done")
>
>
> ----------------------- output:
>
>   >>> m.do_something()
>   >>> m.important
> 43
>   >>>
>   >>> del m
> destroyed signal: function
>   >>> print(h.important)
> 43
>   >>>
>   >>> print("Done")
> Done
>
>


-- 
Christian Tismer             :^)   <mailto:tismer at stackless.com>
Software Consulting          :     Have a break! Take a ride on Python's
Karl-Liebknecht-Str. 121     :    *Starship* http://starship.python.net/
14482 Potsdam                :     PGP key -> http://pgp.uni-mainz.de
phone +49 173 24 18 776  fax +49 (30) 700143-0023
PGP 0x57F3BF04       9064 F4E1 D754 C2FF 1619  305B C09C 5A3B 57F3 BF04
       whom do you want to sponsor today?   http://www.stackless.com/




More information about the PySide mailing list