如果 .connect 采用 lambda 函数,为什么主线程会被阻塞?
How come the main thread is blocked if .connect takes a lambda function?
我试图让一个按钮启动一个新线程,该线程只休眠 30 秒。但是,如果槽是 lambda 函数,主线程将被阻塞。有谁知道为什么会这样,而不是像我期望的那样表现?这是我的代码:
# ...
def setup(self):
# ...
self.pushButton_TestConnection.clicked.connect(self.process)
def process(self):
self.worker_thread = QtCore.QThread()
self.worker = Worker()
self.worker.moveToThread(self.worker_thread)
self.worker_thread.started.connect(lambda: self.worker.sleep(30))
self.worker_thread.start()
class Worker(QtCore.QObject):
def sleep(self, secs):
time.sleep(secs)
它适用于以下
self.worker_thread.started.connect(self.worker.sleep)
self.worker_thread.start()
class Worker(QtCore.QObject):
def sleep(self):
time.sleep(30)
谢谢
在 Qt 中执行代码的线程由接收信号的对象的 thread affinity 决定。如果直接从不同的线程调用对象方法,它将在调用线程中执行,无论被调用对象的线程关联如何。
Lambdas 和其他 python 可调用对象没有线程关联(毕竟它们不是 QObjects,这只是 PyQt 的一个很好的特性,允许您将信号连接到任何 python 可调用对象), 因此它们将始终在主 (GUI) 线程中执行。
所以在这种情况下,lambda 在 GUI 线程中执行,因此 worker.sleep
调用也将在那里执行,并将阻塞它直到调用 returns.
要使其正常工作,您需要将 started
信号直接连接到 Worker 对象的插槽,或者使用您从 lambda 发出的信号与 Worker 通信。
我试图让一个按钮启动一个新线程,该线程只休眠 30 秒。但是,如果槽是 lambda 函数,主线程将被阻塞。有谁知道为什么会这样,而不是像我期望的那样表现?这是我的代码:
# ...
def setup(self):
# ...
self.pushButton_TestConnection.clicked.connect(self.process)
def process(self):
self.worker_thread = QtCore.QThread()
self.worker = Worker()
self.worker.moveToThread(self.worker_thread)
self.worker_thread.started.connect(lambda: self.worker.sleep(30))
self.worker_thread.start()
class Worker(QtCore.QObject):
def sleep(self, secs):
time.sleep(secs)
它适用于以下
self.worker_thread.started.connect(self.worker.sleep)
self.worker_thread.start()
class Worker(QtCore.QObject):
def sleep(self):
time.sleep(30)
谢谢
在 Qt 中执行代码的线程由接收信号的对象的 thread affinity 决定。如果直接从不同的线程调用对象方法,它将在调用线程中执行,无论被调用对象的线程关联如何。
Lambdas 和其他 python 可调用对象没有线程关联(毕竟它们不是 QObjects,这只是 PyQt 的一个很好的特性,允许您将信号连接到任何 python 可调用对象), 因此它们将始终在主 (GUI) 线程中执行。
所以在这种情况下,lambda 在 GUI 线程中执行,因此 worker.sleep
调用也将在那里执行,并将阻塞它直到调用 returns.
要使其正常工作,您需要将 started
信号直接连接到 Worker 对象的插槽,或者使用您从 lambda 发出的信号与 Worker 通信。