当连接类型 = Qt.DirectConnection 时,来自线程对象的 PyQt5 信号会导致段错误

Posted

技术标签:

【中文标题】当连接类型 = Qt.DirectConnection 时,来自线程对象的 PyQt5 信号会导致段错误【英文标题】:PyQt5 signal from threaded object causes segfault when connection type = Qt.DirectConnection 【发布时间】:2019-03-18 17:50:13 【问题描述】:

我有一些 PyQt5 python 代码可以下载一组文件。我正在使用 multiprocessing.dummy 作为线程的包装器,使用 apply_async 来获得同时下载。 从我的线程函数中,我想更新主 gui 中的进度条,但是当我这样做时,QT 为信号选择一个排队连接,并且主线程中播放下载文件的函数启动(文件已下载),然后,进度条突然更新,报告文件正在下载,即使文件已经下载了一段时间。

如果我使用 Qt.DirectConnection 创建信号,我会得到所需的行为,但在文件下载后我会遇到段错误,并且主线程退出。我确信一定有办法解决这个问题,因为这不是一项不寻常的任务,但是在尝试了互斥锁、信号到信号以及许多其他尝试之后,我几乎要把头发扯掉了。我相信答案是显而易见的。

我在这里阅读了其他类似问题的答案,但没有什么特别有启发性的。

PyQt5 Signals and Threading

建议从创建的线程内部进行连接,但我不愿意尝试这个,因为线程是在一个组合到主线程中的自定义对象的类中创建的,我真的不想通过向下引用层次结构。如果我必须这样做,但我尝试在线程函数中连接一个信号来调用类中的方法,然后调用该信号,但没有运气,只是结果相同。

非常感谢。

【问题讨论】:

请提供minimal reproducible example。 代码在github的dependencies分支下。我现在将创建一个最小的示例,但同时这里是链接 - 有问题的代码在文件 packages.py 中,函数是 download_packages。 github.com/millerthegorilla/fedkx/tree/dependencies 连接在 kxfed.py 的第 67 行。如果我在连接代码中添加 'type=Qt.DirectConnection' 就会出现问题 我真的不能用 pyqt 做一个最小的、完整的和可验证的例子。我必须使用 pyuic 创建一个新的主窗口,然后对其余部分进行编码,这肯定不会是最小的。 【参考方案1】:

我最终发现段错误是由于我在调用 thread_pool.apply_async 后从主线程加入线程池引起的。我删除了 close 和 join 语句,并且信号上的直接连接工作正常,正如预期的那样。我继续收到警告:

QObject::setParent: Cannot set parent, new parent is in a different thread

但程序按预期运行。 谢谢!

【讨论】:

该警告很重要,所以请不要简单地忽略它。您的程序可能看起来运行正常,但仍然存在潜在问题。 谢谢。这是我的第一个 QT 和第二个 Python 应用程序,我最终发现我将整个 qt 信号倒退了。我试图在将调用超类方法的子类上定义信号。最终,我意识到我需要在超类中定义信号,然后将对这些信号的引用传递给子类。

以上是关于当连接类型 = Qt.DirectConnection 时,来自线程对象的 PyQt5 信号会导致段错误的主要内容,如果未能解决你的问题,请参考以下文章

当其中一种数据类型可以为空而另一种不能为空时,是不是可以使用 linq 进行匿名连接? [复制]

当连接类型 = Qt.DirectConnection 时,来自线程对象的 PyQt5 信号会导致段错误

当必须接受许多连接时,我在客户端/服务器类型应用程序中遇到 Java 套接字问题

如何使用 GraphQL Relay 连接修复循环依赖

这种类型的连接称为啥连接,连接在最后是合格的?

sql server 表连接类型