如果.connect接受lambda函数,主线程如何被阻止?

时间:2015-02-20 07:43:35

标签: python qt pyqt

我试图让一个按钮旋转一个新的线程,除了睡眠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)

由于

1 个答案:

答案 0 :(得分:3)

在Qt中,执行代码的线程由接收信号的对象的thread affinity确定。如果直接从另一个线程调用一个objects方法,它将在调用线程中执行,无论被调用对象的线程亲和性如何。

Lambdas和其他python callables没有线程关联(毕竟它们不是QObjects,它只是PyQt的一个很好的特性,允许你将信号连接到任何python可调用的),所以它们总是会在主(GUI)线程。
因此,在这种情况下,lambda在GUI线程中执行,因此worker.sleep调用也将在那里执行,并将阻止它直到调用返回。

要使其工作,您需要将started信号直接连接到Worker对象的插槽,或使用您从lambda发出的信号与Worker通信。