[PyKDE] PyQt4/win32 crash

K.S.Sreeram sreeram at tachyontech.net
Fri Sep 15 21:58:04 BST 2006

[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?


(ps: this message was resent without pgp/mime signing. pgp signing seems
to be confusing mailman archives!)
-------------- next part --------------
import sys
from PyQt4 import QtCore, QtGui

window_list = []

class MyWindow( QtGui.QWidget ) :
    def __init__( self ) :
        QtGui.QWidget.__init__( self )
        self.label = QtGui.QLabel( 'Hi There!' )
        layout = QtGui.QVBoxLayout()
        layout.addWidget( self.label )
        self.setLayout( layout )
        window_list.append( self )

    def closeEvent( self, ev ) :
        window_list.remove( self )
        QtGui.QWidget.closeEvent( self, ev )

class MainWindow( QtGui.QWidget ) :
    def __init__( self ) :
        QtGui.QWidget.__init__( self )
        self.button = QtGui.QPushButton( 'Click Me!' )
        layout = QtGui.QVBoxLayout()
        layout.addWidget( self.button )
        self.setLayout( layout )
        self.connect( self.button, QtCore.SIGNAL('clicked()'), self._onClick )

    def _onClick( self ) :
        w = MyWindow()

def main() :
    app = QtGui.QApplication( sys.argv )
    w = MainWindow()

if __name__ == '__main__' :

More information about the PyQt mailing list