PyQt – 在不同线程中创建的对象的信号不起作用
PyQt – Signal for object created in different thread doesn't work
我在 PyQt5 和 Python 3.5 中通过 运行 a Worker
inside a QThread
实现多线程。在以下示例中 thread2_worker
(在辅助线程内运行并)创建 thread3_worker
,将 thread3_worker.finished
信号连接到 thread3_worker_finished()
并运行它。
当 thread3_worker
完成后,它会从其线程中发出 finished
,但连接不起作用。我的猜测是它与不在主线程中创建或连接的 thread3_worker
有关,但我欢迎任何澄清。
import time
from PyQt5.QtCore import QObject, QThread, pyqtSignal, pyqtSlot, QCoreApplication
class Worker(QObject):
# Generic worker.
finished = pyqtSignal()
def __init__(self, func):
super().__init__()
self.func = func
def run(self):
self.func()
self.finished.emit()
def thread_factory(func):
# Creates a Worker, a QThread and moves the Worker inside the QThread.
worker = Worker(func)
thread = QThread()
worker.moveToThread(thread)
thread.started.connect(worker.run)
# Provision graceful termination.
worker.finished.connect(thread.quit)
worker.finished.connect(worker.deleteLater)
thread.finished.connect(thread.deleteLater)
return worker, thread
def wait():
print("thread3:\t{}".format(QThread.currentThread()))
time.sleep(3)
# finished signal of thread3_worker is never received.
@pyqtSlot()
def thread3_worker_finished():
QCoreApplication.exit()
def create_thread3():
print("thread2:\t{}".format(QThread.currentThread()))
global thread3_worker, thread3
# thread3_worker runs inside thread3, and all it does is call wait().
thread3_worker, thread3 = thread_factory(wait)
thread3_worker.finished.connect(thread3_worker_finished) # FIXME Doesn't work.
thread3.start()
app = QCoreApplication([])
print("Main thread:\t{}".format(QThread.currentThread()))
thread3_worker, thread3 = None, None
# thread2_worker runs inside thread2, and creates and runs thread3_worker.
thread2_worker, thread2 = thread_factory(create_thread3)
thread2.start()
app.exec_()
跨线程信号需要事件循环。您的 thread_factory
函数将 worker 的 finished
信号连接到其线程的 quit
插槽。 quit
插槽要求线程退出其事件循环。
所以thread3启动后,worker2结束,thread2退出。然后当 worker3 的 finished
信号发出时,不再有事件循环 运行 可以处理它。如果您注释掉行 worker.finished.connect(thread.quit)
,您的示例应该有效。
我在 PyQt5 和 Python 3.5 中通过 运行 a Worker
inside a QThread
实现多线程。在以下示例中 thread2_worker
(在辅助线程内运行并)创建 thread3_worker
,将 thread3_worker.finished
信号连接到 thread3_worker_finished()
并运行它。
当 thread3_worker
完成后,它会从其线程中发出 finished
,但连接不起作用。我的猜测是它与不在主线程中创建或连接的 thread3_worker
有关,但我欢迎任何澄清。
import time
from PyQt5.QtCore import QObject, QThread, pyqtSignal, pyqtSlot, QCoreApplication
class Worker(QObject):
# Generic worker.
finished = pyqtSignal()
def __init__(self, func):
super().__init__()
self.func = func
def run(self):
self.func()
self.finished.emit()
def thread_factory(func):
# Creates a Worker, a QThread and moves the Worker inside the QThread.
worker = Worker(func)
thread = QThread()
worker.moveToThread(thread)
thread.started.connect(worker.run)
# Provision graceful termination.
worker.finished.connect(thread.quit)
worker.finished.connect(worker.deleteLater)
thread.finished.connect(thread.deleteLater)
return worker, thread
def wait():
print("thread3:\t{}".format(QThread.currentThread()))
time.sleep(3)
# finished signal of thread3_worker is never received.
@pyqtSlot()
def thread3_worker_finished():
QCoreApplication.exit()
def create_thread3():
print("thread2:\t{}".format(QThread.currentThread()))
global thread3_worker, thread3
# thread3_worker runs inside thread3, and all it does is call wait().
thread3_worker, thread3 = thread_factory(wait)
thread3_worker.finished.connect(thread3_worker_finished) # FIXME Doesn't work.
thread3.start()
app = QCoreApplication([])
print("Main thread:\t{}".format(QThread.currentThread()))
thread3_worker, thread3 = None, None
# thread2_worker runs inside thread2, and creates and runs thread3_worker.
thread2_worker, thread2 = thread_factory(create_thread3)
thread2.start()
app.exec_()
跨线程信号需要事件循环。您的 thread_factory
函数将 worker 的 finished
信号连接到其线程的 quit
插槽。 quit
插槽要求线程退出其事件循环。
所以thread3启动后,worker2结束,thread2退出。然后当 worker3 的 finished
信号发出时,不再有事件循环 运行 可以处理它。如果您注释掉行 worker.finished.connect(thread.quit)
,您的示例应该有效。