如果 .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 通信。