PyQt crashing out as a Windows APPCRASH
Question: I have a [very short PyQt program](http://pythonfiddle.com/pyqt-crashing-
example) (n.b. that is a PythonFiddle link - this seems to crash horribly in
Firefox, so code is also posted below) which prints output to a `QTextEdit`
(using code [from this SO
answer](http://stackoverflow.com/questions/8356336/how-to-capture-output-of-
pythons-interpreter-and-show-in-a-text-widget)). When I run the code (on
Windows), it results in an APPCRASH. Some observations:

  * if I add a `time.sleep` call (i.e. uncomment out line 53), then the program completes fine
  * if I don’t redirect the output to the QEdit (i.e. comment out line 34) then it works regardless of whether the `time.sleep` call is commented out or not

I assume that this implies that the code redirecting the `stdout` is broken
somehow - but I'm struggling to understand what's wrong with it to result in
this behaviour - any pointers gratefully received!

* * *

**Full error message**

Problem signature:  
Problem Event Name: APPCRASH  
Application Name: pythonw.exe  
Application Version: 0.0.0.0  
Application Timestamp: 5193f3be  
Fault Module Name: QtGui4.dll  
Fault Module Version: 4.8.5.0  
Fault Module Timestamp: 52133a81  
Exception Code: c00000fd  
Exception Offset: 00000000005cbdb7  
OS Version: 6.1.7601.2.1.0.256.48  
Locale ID: 2057  
Additional Information 1: 5c9c  
Additional Information 2: 5c9c27bb85eb40149b414993f172d16f  
Additional Information 3: bc7e  
Additional Information 4: bc7e721eaea1ec56417325adaec101aa

* * *

Pythonfiddle crashes horribly on Firefox (for me at least), so code below too:

    
    
    import os, sys, time, calendar, math
    from PyQt4 import QtCore, QtGui
    
    class EmittingStream(QtCore.QObject): 
      textWritten = QtCore.pyqtSignal(str)
    
      def write(self, text): self.textWritten.emit(str(text))
    
    class myWrapper(QtGui.QMainWindow):
    
      def __init__(self):
        super(myWrapper, self).__init__()
        self.toolbar = self.addToolBar("MainMenu")
        self.toolbar.addAction(QtGui.QAction("myProg", self, triggered=self.myProgActions))
    
      def myProgActions(self): self.setCentralWidget(myWidget())
    
    class myWidget(QtGui.QWidget):
    
      def __init__(self):
        super(myWidget, self).__init__()
    
        self.myBtn = QtGui.QPushButton('Run!', self)
        self.myBtn.clicked.connect(self.startTest)
        self.outputViewer = QtGui.QTextEdit()
    
        self.grid = QtGui.QGridLayout()
        self.grid.addWidget(self.myBtn)
        self.grid.addWidget(self.outputViewer)
        self.setLayout(self.grid)
    
      def startTest(self):
        self.myLongTask = TaskThread()
        sys.stdout = EmittingStream(textWritten=self.normalOutputWritten)
        self.myLongTask.start()
    
      def normalOutputWritten(self, text):
        cursor = self.outputViewer.textCursor()
        cursor.movePosition(QtGui.QTextCursor.End)
        cursor.insertText(text)
        self.outputViewer.setTextCursor(cursor)
        self.outputViewer.ensureCursorVisible()
        QtGui.qApp.processEvents()
    
    class TaskThread(QtCore.QThread):
      def __init__(self): super(TaskThread, self).__init__()
      def run(self): myProgClass()
    
    class myProgClass:
      def __init__(self):
        for i in range(0,100):
          print "thread", i+1, " ", math.sqrt(i)
          #time.sleep(0.005)
    
    if __name__ == '__main__':
      app = QtGui.QApplication(sys.argv)
      myApp = myWrapper()
      myApp.show()
      sys.exit(app.exec_())
    


Answer: Ok, one thing first about the thread safety of your program. Because you are
connecting a `QObject` to stdout, calls to `print` will interact with this
`QObject`. But you should only interact with a `QObject` from the thread it
was created in. The implementation you have is potentially thread **unsafe**
if you call `print` from a thread other than the one the `QObject` resides in.

In your case, you are calling `print` from a `QThread` while the
`EmmittingStream(QObject)` resides in the main thread. I suggest you thus
change your code to make it threadsafe, like so:

    
    
    self.myLongTask = TaskThread()
    sys.stdout = EmittingStream(textWritten=self.normalOutputWritten)
    sys.stdout.moveToThread(self.myLongTask)
    self.myLongTask.start()
    

**Note that now calling`print` from the MainThread of your application will
result in thread-unsafe behaviour. Since you aren't doing that at the moment,
you are OK for now, but be warned!**

I really suggest you read <http://qt-project.org/doc/qt-4.8/threads-
qobject.html> and get your head around everything it talks about.
Understanding that document is the key to avoiding annoying crashes due to
threads.

\--

Now, The issue with the crash is apparently caused by your call to
`processEvents()`. I haven't worked out **why** (I imagine it is related to
threads somehow...), but I can tell you that you do not need that line!
Because you are using signals/slots, once the `normalOutputWritten` method
runs, control returns to the Qt Event Loop anyway, and it will continue to
process events as normal. There is thus no need to force Qt to process events!

Hope that helps!

**EDIT:** For an example of how to make your `EmittingStream`/`print` calls
thread-safe, see here: [Redirecting stdout and stderr to a PyQt4 QTextEdit
from a secondary
thread](http://stackoverflow.com/questions/21071448/redirecting-stdout-and-
stderr-to-a-pyqt4-qtextedit-from-a-secondary-thread/21071865#21071865)

