[PyQt] Crash (segfault) when using PyQt4 Qthread

chris3110 chris31103110 at yahoo.fr
Thu Oct 30 22:25:08 GMT 2008


Hi there,

I'm getting a systematic crash when trying to log the output of a Qthread to
a parent window. I'm using Qt 4 on Fedora Core 9 with Python 2.5.1:

>rpm -q PyQt4 python
PyQt4-4.4.2-2.fc9.i386
python-2.5.1-26.fc9.i386

The following sample code crashes after a few iterations when clicking in
and out of the log window, moving it around, etc... sufficiently.  If you
don't touch the window at all it doesn't crash though.

Can someone explain what's going on here ?  Is there something wrong with my
threading architecture ?  I guess the code should not give a segfault
anyway.

Thanks for your help,
Chris

--------------------snip---------------snip-------------------
#!/usr/bin/python

import sys
import logging
import time
from PyQt4 import QtGui, QtCore, uic
from PyQt4.QtCore import QString, QThread
from PyQt4.QtGui import *

logging.basicConfig(level=logging.INFO)

class Page:
    def __init__(self):
        self.log = logging.getLogger('u.crawler')
        
    def analyze(self):
        for i in xrange(30):
            self.log.info('Line %d', i)
            time.sleep(2)

class CrawlerThread(QThread):
    def __init__(self, page):
        self.page = page
        QThread.__init__ (self)
        
    def run(self):
        page = self.page
        page.log.info('Starting')
        page.analyze()

class WindowLogger(logging.Handler):
    def __init__(self, window):
        self.window = window
        logging.Handler.__init__(self)
        
    def emit(self, record):
        self.window.appendPlainText(record.getMessage())


(urlFormUi, urlFormBase) = uic.loadUiType('urlForm.ui')

class UrlCrawler(urlFormUi, urlFormBase):
    
    threadList = []

    def __init__(self):
        urlFormBase.__init__(self)
        self.setupUi(self)

        self.log = logging.getLogger('u.crawler')
        self.log.addHandler(WindowLogger(self.winlog))

    def accept(self):
        thread = CrawlerThread(Page())
        UrlCrawler.threadList.append(thread)
        thread.start()

    def reject(self):
        self.close()
        
    def closeEvent(self, event):
        event.accept()


if __name__ == "__main__":
    app = QtGui.QApplication([])
    app.main = UrlCrawler()
    app.main.show()
    sys.exit(app.exec_())
--------------------snip---------------snip-------------------

You'll also need the following urlForm.ui file in ordre to run the sample. 
Click "Ok" to start the thread.

--------------------snip---------------snip-------------------
<ui version="4.0" >
 <class>dialog</class>
 <widget class="QDialog" name="dialog" >
  <property name="geometry" >
   <rect>
    <x>0</x>
    <y>0</y>
    <width>435</width>
    <height>472</height>
   </rect>
  </property>
  <property name="windowTitle" >
   <string>Test</string>
  </property>
  <widget class="QDialogButtonBox" name="buttonBox" >
   <property name="geometry" >
    <rect>
     <x>250</x>
     <y>10</y>
     <width>181</width>
     <height>32</height>
    </rect>
   </property>
   <property name="orientation" >
    <enum>Qt::Horizontal</enum>
   </property>
   <property name="standardButtons" >
    <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
   </property>
  </widget>
  <widget class="QPlainTextEdit" name="winlog" >
   <property name="geometry" >
    <rect>
     <x>10</x>
     <y>50</y>
     <width>421</width>
     <height>411</height>
    </rect>
   </property>
   <property name="horizontalScrollBarPolicy" >
    <enum>Qt::ScrollBarAlwaysOff</enum>
   </property>
   <property name="readOnly" >
    <bool>true</bool>
   </property>
  </widget>
 </widget>
 <resources/>
 <connections>
  <connection>
   <sender>buttonBox</sender>
   <signal>accepted()</signal>
   <receiver>dialog</receiver>
   <slot>accept()</slot>
   <hints>
    <hint type="sourcelabel" >
     <x>248</x>
     <y>254</y>
    </hint>
    <hint type="destinationlabel" >
     <x>157</x>
     <y>274</y>
    </hint>
   </hints>
  </connection>
  <connection>
   <sender>buttonBox</sender>
   <signal>rejected()</signal>
   <receiver>dialog</receiver>
   <slot>reject()</slot>
   <hints>
    <hint type="sourcelabel" >
     <x>316</x>
     <y>260</y>
    </hint>
    <hint type="destinationlabel" >
     <x>286</x>
     <y>274</y>
    </hint>
   </hints>
  </connection>
 </connections>
</ui>
--------------------snip---------------snip-------------------

-- 
View this message in context: http://www.nabble.com/Crash-%28segfault%29-when-using-PyQt4-Qthread-tp20255394p20255394.html
Sent from the PyQt mailing list archive at Nabble.com.



More information about the PyQt mailing list