python UI app hangs while updating stdout output to UI using subprocess.Popen in a for loop
<p>I'm running subprocess.Popen() to call a commandline tool which prints it's output to console like so:</p>

<pre><code>[app] : Initializing...
[app] : Starting process
[app] : .............
[app] : .............
[app] : Extracting information
[app] : Downloading information
[app] : 100% completed              
[app] : Saving file to disk
[app] : Completed
</code></pre>

<p>Now i'm trying to capture the output so I can show this output to my python UI application in realtime. I'm capturing the output like so:</p>

<pre><code>cmd = "..."
p = subprocess.Popen(cmd, shell=True, stdin=PIPE, stdout=PIPE, stderr=STDOUT)
for line in p.stdout:
    self.status.showmsg(str(line.rstrip()))
    p.stdout.flush()
</code></pre>

<p><strong>The problem:</strong> The output are displayed on my UI correctly until it reaches that output line where it shows the percentage of process completed(100% in the example). This is where the UI hangs and the gradual increase of the % is not displayed or any output thereafter. The program is running correctly in the background though(does its thing) and when it's 100% complete, the UI unfreezes.</p>

<p>What am I doing wrong here? Looks to me that (%) output is also another loop and failing there but I don't know why or how to go about handling this in python.</p>

<p>Thanks for the valuable suggestions!</p>

<p>Run the worker process in a separate thread and send the data back to the gui using a custom signal. Here's a very basic demo script:</p>

<pre><code>import sys
from PyQt4 import QtCore, QtGui

class Thread(QtCore.QThread):
    dataReceived = QtCore.pyqtSignal(str)

    def run(self):
        # subprocess stuff goes here
        for step in range(6):
            self.sleep(1)
            self.dataReceived.emit('data received: %d' % step)

class Window(QtGui.QMainWindow):
    def __init__(self):
        super(Window, self).__init__()
        self.button = QtGui.QPushButton('Start')
        self.button.clicked.connect(self.handleButton)
        self.setCentralWidget(self.button)
        self.thread = Thread(self)
        self.thread.dataReceived.connect(self.statusBar().showMessage)

    def handleButton(self):
        if not self.thread.isRunning():
            self.statusBar().showMessage('starting...')
            self.thread.start()

    def closeEvent(self, event):
        self.thread.wait()

if __name__ == "__main__":

    app = QtGui.QApplication(sys.argv)
    window = Window()
    window.resize(200, 60)
    window.show()
    sys.exit(app.exec_())
</code></pre>

python loops subprocess pyqt4 hang