title: Python - Parents and Multithreading issues
body: <p>I am learning PyQT and Multithreading, and I think I need help here. In my code, I have a a class <code>Tool</code>, and a thread <code>TaskThread</code>. From the thread, I call the function <code>dummy_function</code> which perform a proccess being displayed in the GUI by a progress-bar.</p>
  
  <p>When <code>dummy_function</code> finishes, I want to print a message in the GUI, by calling <code>self.outputText.setText("Hello")</code>. However, I get the following error:</p>
  
  <blockquote>
    <p>AttributeError: 'TaskThread' object has no attribute 'outputText'</p>
  </blockquote>
  
  <p>Code:</p>
  
  <pre><code>import sys
  import datetime
  import time
  
  from PyQt4 import QtCore, QtGui, uic
  from PyQt4.QtCore import *
  from PyQt4.QtGui import *
  
  # Link to GUI
  qtCreatorFile = "GUInterface.ui"
  
  Ui_MainWindow, QtBaseClass = uic.loadUiType(qtCreatorFile)
  
  def time_converter_to_unix(start_datetime, end_datetime):
      # Convert QTimeEdit to UNIX Timestamp (int, msec included), and then to float
      start_datetime_unix_int = start_datetime.toMSecsSinceEpoch ()
      start_datetime_unix = (float(start_datetime_unix_int) / 1000)
  
      end_datetime_unix_int = end_datetime.toMSecsSinceEpoch ()
      end_datetime_unix = (float(end_datetime_unix_int) / 1000)
  
      return start_datetime_unix, end_datetime_unix
  
  def dummy_function(self, start_datetime_unix, end_datetime_unix): 
      # Dummy function, just to simulate a task. It takes parameters just for testing.
      result = start_datetime_unix * end_datetime_unix 
  
      # Pre-steps for mapping from one range to other (progress-bar)
      OldMax = 99999
      OldMin = 1
      NewMax = 100
      NewMin = 1
  
      OldRange = (OldMax - OldMin)
      NewRange = (NewMax - NewMin)    
  
      u = 1
      for i in range (OldMax):
          u = i*2
  
          OldValue = i
          print OldValue
          NewValue = (((OldValue - OldMin) * NewRange) / OldRange) + NewMin
          print "NEW VALUE: ", NewValue
  
          self.emit(QtCore.SIGNAL('CPU_VALUE'), NewValue)
  
      self.outputText.setText("Hello")
  
  class Tool(QtGui.QMainWindow, Ui_MainWindow):
      def __init__(self, parent = None):
  
          # Setting-ip UI
          QtGui.QMainWindow.__init__(self)
          Ui_MainWindow.__init__(self)
          self.setupUi(self)
  
          # Button Action
          self.runButton.clicked.connect(self.onStart)
  
          # Progress Bar and Label. At the begining, the bar is at 0
          self.progressBar.setValue(0)
          self.progressBar.setRange(0,100)
          self.resultLabel.setText("Waiting...")  
  
          ####################################
          #TEST: Thread for progress bar
          self.myLongTask = TaskThread()
          self.connect(self.myLongTask, QtCore.SIGNAL('CPU_VALUE'), self.onProgress)
          self.myLongTask.taskFinished.connect(self.onFinished)
          ####################################        
  
      def onStart(self):    
  
          self.progressBar.reset()
          self.resultLabel.setText("In progress...")        
          print "(onStart)In progress mode executed"
  
          print "(onStart)INITIALIZE THREAD"
          self.myLongTask.start()     
          print "(onStart)THREAD EXECUTED"
  
          self.myLongTask.start_dt = self.startTime.dateTime() # &lt;----
          self.myLongTask.end_dt = self.endTime.dateTime()     # &lt;----
  
      def onProgress(self, i):
          self.progressBar.setValue(i)        
  
      def onFinished(self):
          # Stop the pulsation when the thread has finished
          print "(onFinished) executed"
          self.progressBar.setRange(0,1)
          self.progressBar.setValue(1)
          self.resultLabel.setText("Done")        
  
  class TaskThread(QtCore.QThread):  
        taskFinished = QtCore.pyqtSignal()
  
      def __init__(self):
          QtCore.QThread.__init__(self)
  
      def __del__(self):
          self.wait()
  
      def run(self):  
          # First, we read the times from the QDateTime elements in the interface      
          print "Getting times..."
          start_datetime_unix, end_datetime_unix = time_converter_to_unix(self.start_dt, self.end_dt)
  
          # Then, we put these values in my_function
          print "Executing function..."
          dummy_function(self, start_datetime_unix, end_datetime_unix) 
  
          # To finish, we execute onFinished.
          print "Finishing thread..."
          self.taskFinished.emit()
  
  def main():
      app = QtGui.QApplication(sys.argv)
      window = Tool()
      window.show()
      sys.exit(app.exec_())
  
  if __name__ == '__main__':
      main()
  </code></pre>
  
  <p>The <strong>first</strong> thing I tried, it was to add the following line to my <code>onStart</code> function:</p>
  
  <pre><code>...
  self.myLongTask.output_dt = self.outputText
  ...
  </code></pre>
  
  <p>Then, in the <code>TaskThread</code>, I change the call of <code>dummy_function</code> by: </p>
  
  <pre><code>...
  dummy_function(self, start_datetime_unix, end_datetime_unix, self.output_dt) 
  ...
  </code></pre>
  
  <p>To finish, I change my dummy_function by adding this new parameter:</p>
  
  <pre><code>def dummy_function(self, start_datetime_unix, end_datetime_unix, output_text): 
      # Dummy function, just to simulate a task. It takes parameters just for testing.
      result = start_datetime_unix * end_datetime_unix 
  
      # Pre-steps for mapping from one range to other (progress-bar)
      OldMax = 99999
      OldMin = 1
      NewMax = 100
      NewMin = 1
  
      OldRange = (OldMax - OldMin)
      NewRange = (NewMax - NewMin)    
  
      u = 1
      for i in range (OldMax):
          u = i*2
  
          OldValue = i
          print OldValue
          NewValue = (((OldValue - OldMin) * NewRange) / OldRange) + NewMin
          print "NEW VALUE: ", NewValue
  
          self.emit(QtCore.SIGNAL('CPU_VALUE'), NewValue)
  
      output_text.setText("Hello")
  </code></pre>
  
  <p>Now, when it reaches the end, the program just closes showing the following error:</p>
  
  <blockquote>
    <p>QObject: Cannot create children for a parent that is in a different thread.
    (Parent is QTextDocument(0xf13a60), parent's thread is QThread(0xc6f180), current thread is TaskThread(0xee0740)</p>
  </blockquote>
  
  <p>In order to try the program, I uplodaed the <a href="https://drive.google.com/folderview?id=1siYGyHag9Qio3PUGvUrGXi9vufKDzdvJ" rel="nofollow noreferrer">GUInterface</a>, so you can try it if necessary.</p>