Python PyQt4:传统的信号/插槽多线程UI机制?

Python PyQt4:传统的信号/插槽多线程UI机制?,python,multithreading,qt,thread-safety,pyqt,Python,Multithreading,Qt,Thread Safety,Pyqt,有人使用过多线程PyQt4应用程序吗?我只是想知道,与PyQt4框架的QtThread相结合的内置信号/插槽机制是否比使用事件驱动异步回调的标准Python线程(在我的代码中设计用于以线程安全的方式处理UI组件)有任何好处 我正在寻找任何主要的速度或安全问题,任何特定的运行时异常或边缘情况。(UI相当复杂,因此在稍后的阶段重新编写会适得其反) 谢谢 编辑:我意识到这可能意味着复制一些已经存在的PyQt核心功能,但如果它允许应用程序具有更大的灵活性,那就没问题了。如果你没有使用信号和插槽机制,没有

有人使用过多线程PyQt4应用程序吗?我只是想知道,与PyQt4框架的QtThread相结合的内置信号/插槽机制是否比使用事件驱动异步回调的标准Python线程(在我的代码中设计用于以线程安全的方式处理UI组件)有任何好处

我正在寻找任何主要的速度或安全问题,任何特定的运行时异常或边缘情况。(UI相当复杂,因此在稍后的阶段重新编写会适得其反)

谢谢


编辑:我意识到这可能意味着复制一些已经存在的PyQt核心功能,但如果它允许应用程序具有更大的灵活性,那就没问题了。

如果你没有使用信号和插槽机制,没有滚动你自己的事件循环,那么真正使用Qt/PyQt是没有意义的。基本上,您将重新实现框架本身的核心。但我猜这不是你要问的

如果你能澄清一下你的问题,那就太好了(因为我不得不做出一些假设) 但事情是这样的:

我认为您对信号和插槽机制的作用有点困惑。(或者也许不是,请原谅我重复了一些你可能很清楚的东西)

信号和插槽不为您实现线程(因此使用信号/插槽比标准Python线程有任何好处的问题是没有意义的)

您可能假设信号插槽机制是多线程的,并且当信号调用插槽时,它会在新线程中执行。事实并非如此

Qt中的信号和插槽机制在Qt中的单个事件循环中运行(由QApplication实现),而Qt本身在单个线程中运行。 因此,信号和插槽不能以任何方式替代多线程

如果有一个插槽阻塞,那么它将阻塞整个应用程序。 因此,理想情况下,任何阻塞I/O或时间密集型函数都应该位于与UI分离的线程中,并且您的插槽应该开始执行这些线程。 现在,是使用QThread还是标准Python线程来实现自己的线程是另一个问题,以前在StackOverflow上也有人问过这个问题,但我倾向于在Qt应用程序中使用QThreads

因此,如果您有一个按钮,并且您希望在其单击时使用请求库启动文件下载,那么您将QPushButton的
单击
信号连接到一个插槽,例如
downloadButtonClicked
,该插槽将启动一个新的QThread,负责使用请求下载文件。您可以进一步连接来自QThread的finished()信号,以了解下载何时完成并更新UI


(如果这确实是您要问的问题,我将添加一个代码示例。因此,请澄清您的问题)

根据您对另一个答复的评论:


很抱歉,我说的是QT线程插槽/信号 机制与使用内置Python线程的回调。我打算 在事件到达时从UI创建单独的线程(单击等),以及 然后使用从新线程到主UI线程的回调 更新UI(主线程中的所有UI逻辑都带有锁以保留它 线程安全。)我知道这可能意味着复制一些已经存在的 目前PyQt的功能,但我觉得这样我会有更多 控制我的应用程序。(如果允许更多,那么额外的工作就不重要了 应用程序的灵活性。此外,它不需要太多的工作)

我想说的是,您所追求的是使用线程中的
QApplication.postEvent()
。通过一点额外的代码,您可以使用它在主线程中同步或异步执行任意方法

我不确定这两种选择(Qt或Python线程)是否真的有任何优点或缺点。据我所知,它们都仍然持有GIL,这意味着您的程序从来都不是真正的多线程程序
QThread
s附带了一个事件循环,但正如您所说,用自己的Python线程编写并不困难

您是否考虑过使用多进程而不是多线程?虽然启动速度较慢,但实际上代码可以并行运行

最后,我认为你的问题的答案只是个人偏好。我的想法是避免使用
QThread
,因为如果PyQt\PySide\Qt死掉的话,将来可以更容易地将应用程序移植到另一个widget工具包(这不是很可能,但我对PyGTK的体验不好,所以现在我很谨慎)


编辑:请也看看这个,因为它有比我给出的更好的答案:

信号/插槽不使用主线程以外的任何线程。您能否解释一下,您是如何用python线程替换信号/插槽的(这就是您的问题所暗示的)?就我个人而言,我使用线程和信号/插槽,它们的用途非常不同。也许更多关于你的应用程序功能和/或你的线程用途的细节可以帮助我理解!很抱歉,我说的是QtThread插槽/信号机制与使用内置Python线程的回调。我打算在事件到达(单击等)时从UI创建单独的线程,然后使用新线程对主UI线程的回调来更新UI(主线程中的所有UI逻辑都带有锁以保持线程安全)我知道这可能意味着复制一些已经存在的PyQt功能,但我觉得这样我就可以更好地控制我的应用程序。(如果允许应用程序具有更大的灵活性,那么额外的工作就不成问题。另外,这也不需要太多工作)