python - 如果 .connect 采用 lambda 函数,主线程为何会被阻塞?

标签 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)

谢谢

最佳答案

在 Qt 中,执行代码的线程由 thread affinity 决定。接收信号的对象。如果直接从不同的线程调用对象方法,则无论被调用对象的线程关联性如何,该方法都将在调用线程中执行。

Lambda 和其他 Python 可调用对象没有线程亲和性(它们毕竟不是 QObject,这只是 PyQt 的一个很好的功能,允许您将信号连接到任何 Python 可调用对象),因此它们将始终在主(GUI)线程。
因此,在本例中,lambda 是在 GUI 线程中执行的,因此 worker.sleep 调用也将在那里执行,并将阻塞它,直到调用返回。

要实现此功能,您需要将 started 信号直接连接到 Worker 对象的槽,或者使用从 lambda 发出的信号与 Worker 进行通信。

关于python - 如果 .connect 采用 lambda 函数,主线程为何会被阻塞?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28623867/

相关文章:

python - 如何在 GTK 中更新绘图区域

python - 自定义模板标签-返回对象

c++ - 我怎么知道按钮是否被拨动?

python - 如何从 Qt 对话框获取自定义信号

Python 在使用 PyQt 和 matplotlib 时泄漏内存

python - 想要以排序的方式查看字典的合并

python - 如何在 python 中左对齐字符串的一部分?

c++ - Qt Creator IDE 似乎错误地将 reinterpret_cast<::GlobalType> 标记为无效

qt - DropShadow 用于半透明项目

python - 来自网络的 Qt 图片