title: pyqt emit signal from threading thread
body: <p>I'm trying to update a pyqt QProgressBar from multiple threads, and from what I understand the best way to do this is by emitting signals back to the main GUI thread (I tried passing the QProgressBar object to the worker threads and though it did seem to work I got a ton of warnings in the interpreter). In the following code I set up a progressSignal signal and connect it to a thread which (for now) just prints whatever was emitted. I then emit from each thread the total percentage. I know this works outside the threads by just throwing out a random emit in line 47, which does come through. However the emit from line 36 does not trigger anything, so it never seems to make it through...</p>
  
  <pre><code>import Queue, threading
  from PyQt4 import QtCore
  import shutil
  import profile
  
  fileQueue = Queue.Queue()
  
  class Communicate(QtCore.QObject):
  
      progressSignal = QtCore.pyqtSignal(int)
  
  class ThreadedCopy:
      totalFiles = 0
      copyCount = 0
      lock = threading.Lock()
  
      def __init__(self, inputList, progressBar="Undefined"):
          self.totalFiles = len(inputList)
  
          self.c = Communicate()
          self.c.progressSignal.connect(self.updateProgressBar)
  
          print str(self.totalFiles) + " files to copy."
          self.threadWorkerCopy(inputList)
  
  
      def CopyWorker(self):
          while True:
              self.c.progressSignal.emit(2000)
              fileName = fileQueue.get()
              shutil.copy(fileName[0], fileName[1])
              fileQueue.task_done()
              with self.lock:
                  self.copyCount += 1
                  percent = (self.copyCount * 100) / self.totalFiles
                  self.c.progressSignal.emit(percent)
  
      def threadWorkerCopy(self, fileNameList):
  
          for i in range(16):
              t = threading.Thread(target=self.CopyWorker)
              t.daemon = True
              t.start()
          for fileName in fileNameList:
              fileQueue.put(fileName)
          fileQueue.join()
          self.c.progressSignal.emit(1000)
  
      def updateProgressBar(self, percent):
          print percent
  </code></pre>
  
  <p>UPDATE:</p>
  
  <p>Heres a sample with a gui. This one runs but is quite unstable, it crashes regularly and the UI does some weird stuff (progress bar not completing, etc.)</p>
  
  <p>Main.py:</p>
  
  <pre><code>import sys, os
  import MultithreadedCopy_5
  from PyQt4 import QtCore, QtGui
  
  def grabFiles(path):
      # gets all files (not folders) in a directory
      for file in os.listdir(path):
          if os.path.isfile(os.path.join(path, file)):
              yield os.path.join(path, file)
  
  class MainWin(QtGui.QWidget):
  
      def __init__(self):
          super(MainWin, self).__init__()
          self.initUI()
  
      def initUI(self):
          self.progress = QtGui.QProgressBar()
  
          box = QtGui.QVBoxLayout()
          box.addWidget(self.progress)
          goBtn = QtGui.QPushButton("Start copy")
          box.addWidget(goBtn)
  
          self.setLayout(box)
  
          goBtn.clicked.connect(self.startCopy)
  
      def startCopy(self):
          files = grabFiles("folder/with/files")
          fileList = []
          for file in files:
              fileList.append([file,"folder/to/copy/to"])
  
          MultithreadedCopy_5.ThreadedCopy(fileList, self.progress)
  
  def main():
      app = QtGui.QApplication(sys.argv)
      ex = MainWin()
      ex.show()
      sys.exit(app.exec_())
  
  if __name__ == "__main__":
      main()
  </code></pre>
  
  <p>MultithreadedCopy_5.py:</p>
  
  <pre><code>import Queue, threading
  from PyQt4 import QtCore
  import shutil
  import profile
  
  fileQueue = Queue.Queue()
  
  class Communicate(QtCore.QObject):
  
      progressSignal = QtCore.pyqtSignal(int)
  
  class ThreadedCopy:
      totalFiles = 0
      copyCount = 0
      lock = threading.Lock()
  
      def __init__(self, inputList, progressBar="Undefined"):
          self.progressBar = progressBar
          self.totalFiles = len(inputList)
  
          self.c = Communicate()
          self.c.progressSignal.connect(self.updateProgressBar, QtCore.Qt.DirectConnection)
  
          print str(self.totalFiles) + " files to copy."
          self.threadWorkerCopy(inputList)
  
  
      def CopyWorker(self):
          while True:
              fileName = fileQueue.get()
              shutil.copy(fileName[0], fileName[1])
              fileQueue.task_done()
              with self.lock:
                  self.copyCount += 1
                  percent = (self.copyCount * 100) / self.totalFiles
                  self.c.progressSignal.emit(percent)
  
      def threadWorkerCopy(self, fileNameList):
          for i in range(16):
              t = threading.Thread(target=self.CopyWorker)
              t.daemon = True
              t.start()
          for fileName in fileNameList:
              fileQueue.put(fileName)
          fileQueue.join()
  
      def updateProgressBar(self, percent):
          self.progressBar.setValue(percent)
  
  #profile.run('ThreadedCopy()')
  </code></pre>