K.S.Sreeram wrote: > Phil Thompson wrote: >> On Friday 15 September 2006 9:58 pm, K.S.Sreeram wrote: >>> [Qt-4.1.4, sip-4.4.5, PyQt-4.0.1, Python-2.4.3, MSVC-7.1] >>> >>> Hi all, >>> >>> I've been facing a random crash in my app for sometime, and i've got it >>> down to a simple test program. Run the attached script, click "Click Me" >>> and close the newly opened window, and it crashes! >>> >>> I used debug builds and poked around the code, and here's why i think >>> its crashing... >>> >>> The crash happens when a top-level window is closed, and all python >>> references to the window are lost in the 'closeEvent' method. >>> >>> When a window is closed using the close button at the right top of the >>> window, the Qt function "QWidgetPrivate::close_helper(mode)" gets called >>> with "mode == CloseWithSpontaneousEvent". This function is there in >>> src/gui/kernel/qwidget.cpp line 4609. >>> >>> In this function, close event is sent to the widget if mode is >>> CloseWithSpontaneousEvent, as in this case. By the time, the close event >>> is handled by the widget, the widget is already deleted because of >>> python's gc. >>> >>> The Qt code seems to check for this case using tests like >>> "that.isNull()". But on line 4642, the check for null is not performed >>> and the app crashes at that point. >>> >>> So this looks like it is a bug in Qt itself. But is there someway PyQt >>> can workaround this bug? >> What if you swap the two lines of MyWindow.closeEvent()? > > That doesn't help. The last python reference is actually the 'self' > parameter to the closeEvent. So the python gc kicks in only /after/ the > return from closeEvent. > > As a workaround, i'm currently just planning to use a single shot timer > to keep a reference to the object until after the close fully completes.
Here's the actual workaround i'm using:
_delayed = []
_timer = None
def _onTimer() :
global _timer
del _delayed[:]
_timer = None
def delaygc( obj ) :
global _timer
_delayed.append( obj )
if _timer is not None :
_timer.stop()
_timer = QtCore.QTimer()
_timer.setSingleShot( True )
_timer.start( 1000 )
QtCore.QObject.connect( _timer, QtCore.SIGNAL('timeout()'), _onTimer )
Just insert 'delaygc(self)' into 'closeEvent' methods and the app
doesn't crash anymore!
[sreeram;]
signature.asc
Description: OpenPGP digital signature
_______________________________________________ PyKDE mailing list [email protected] http://mats.imk.fraunhofer.de/mailman/listinfo/pykde
