How to call widget's method from QThread
<p>The code runs but prints out the error: <code>QObject::setParent: Cannot set parent, new parent is in a different thread</code>.</p>

<p>What could be a reason?</p>

<p><a href="https://i.stack.imgur.com/AQOkW.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/AQOkW.png" alt="enter image description here"></a></p>

<pre><code>import Queue, threading
from PyQt4 import QtGui, QtCore
app = QtGui.QApplication([])    

class MessageBox(QtGui.QMessageBox):
    def __init__(self, parent=None):
        QtGui.QMessageBox.__init__(self, parent)     

    def showMessage(self):
        self.setText('Completed')
        self.show()

class Thread(QtCore.QThread):
    def __init__(self, queue, parent=None):
        QtCore.QThread.__init__(self, parent)     
        self.queue=queue        

    def run(self):    
        while True:
            number=self.queue.get()
            result = self.process(number)
            messagebox.showMessage()
            self.queue.task_done()

    def process(self, number):
        timer = QtCore.QTimer()
        for i in range(number):
            print 'processing: %s'%i
            QtCore.QThread.sleep(1)        
        return True    

messagebox = MessageBox()

queue = Queue.Queue()
thread = Thread(queue)
thread.start()

lock=threading.Lock()
lock.acquire()
queue.put(3)
lock.release()    
app.exec_()
</code></pre>

<p>In an example posted below we are reaching the widget's method using signal and slot mechanism (instead of calling it directly from the thread). The code execution works as expected. Even while I "know" the solution I would like to know why it is happening. </p>

<pre><code>class Emitter(QtCore.QObject):
    signal = QtCore.pyqtSignal()

class MessageBox(QtGui.QMessageBox):
    def __init__(self, parent=None):
        QtGui.QMessageBox.__init__(self, parent)     

    def showMessage(self):
        self.setText('Completed')
        self.show()

class Thread(QtCore.QThread):
    def __init__(self, queue, parent=None):
        QtCore.QThread.__init__(self, parent)     
        self.queue=queue        

    def run(self):
        emitter = Emitter()
        emitter.signal.connect(messagebox.showMessage)  

        while True:
            number=self.queue.get()
            result = self.process(number)
            emitter.signal.emit()
            self.queue.task_done()

    def process(self, number):
        timer = QtCore.QTimer()
        for i in range(number):
            print 'processing: %s'%i
            QtCore.QThread.sleep(1)        
        return True

messagebox = MessageBox()

queue = Queue.Queue()
thread = Thread(queue)
thread.start()

lock=threading.Lock()
lock.acquire()
queue.put(3)
lock.release()

app.exec_()
</code></pre>