Cannot send posted events for objects in another t

2019-02-26 06:32发布

问题:

When I try to use one QDialog object from threads I get this error. Here is the code I'm using:

import threading
import test_qdialog
from PyQt4 import QtGui, QtCore


class MyThread(threading.Thread):
    def __init__(self, id, window, mutex):
        self.id = id
        self.window = window
        self.mutex = mutex
        super(MyThread, self).__init__()

    def run(self):
        with self.mutex:
            result = self.window.exec_()
            if result == QtGui.QDialog.Accepted:
                print "Thread %d: %s" % (self.id, self.window.message_input.text())


if __name__ == "__main__":
    import sys
    app = QtGui.QApplication(sys.argv)

    mutex = threading.Lock()
    threads = []
    window = test_qdialog.MyDialog()

    for i in range(5):
        thread = MyThread(i, window, mutex)
        thread.start()
        threads.append(thread)

    for thread in threads:
        thread.join()

    sys.exit(app.exec_())

As written in this answer, if I get it right, I can't do it this way. But how can I do it then?

回答1:

You can only create and use GUI widgets on main thread (every UI library that I know is like that). However, you can easily pass signals from threads to main using QtCore.QtThread. See for example the answer to PyQt threads and signals - how to properly retrieve values (even if the answer is not what the OP was looking for, it is relevant to your situation). May also find this SO post useful.

So instead of creating or accessing the dialog from thread, you would emit a signal from thread, and have your main window connected to it create the dialog when it receives the signal. Qt takes care of transfering data between threads. Will work like a charm.

Definitely take a close look at Qt Threading Basics, if you haven't already (if you have, may want to post questions about parts you don't understand, there is tons of important info there).