0

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

我正在寻找任何主要的速度或安全问题、任何特定的运行时异常或边缘情况。(用户界面非常复杂,因此在后期重新编写会适得其反)。

谢谢。

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

4

2 回答 2

0

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

抱歉含糊不清,我在谈论 QtThread 插槽/信号机制与使用内置 Python 线程的回调。我打算在事件到达时(点击等)从 UI 创建单独的线程,然后使用从新线程到主 UI 线程的回调来更新 UI(主线程中的所有 UI 逻辑都带有锁以保持线程安全。)我知道这可能意味着复制一些已经存在的 PyQt 功能,但我觉得这样我可以更好地控制我的应用程序。(如果它允许应用程序具有更大的灵活性,则无需担心额外的工作。此外,它的工作量也不大)

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

我不确定这两个选项(Qt 或 Python 线程)是否真的有任何优点或缺点。据我所知,他们都仍然持有 GIL,这意味着您的程序永远不是真正的多线程。QThreads 带有一个事件循环,但正如您所说,在您自己的 Python 线程中编写自己并不难。

您是否考虑过使用多个进程而不是多个线程?虽然启动速度较慢,但​​您可以获得实际让代码并行运行的优势。

归根结底,我认为您问题的答案只是个人喜好。我的做法是避免使用 a QThread,因为如果 PyQt\PySide\Qt 死了(不是很有可能,但我对 PyGTK 的体验很糟糕,所以将来可以更容易地将您的应用程序移植到另一个小部件工具包)现在我很警惕)

编辑:也请看一下这个,因为它的答案比我给出的要好得多:PyQt 应用程序中的线程:使用 Qt 线程还是 Python 线程?

于 2013-10-21T22:46:16.307 回答
0

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

如果您能稍微澄清一下您的问题,那就太好了(因为我不得不做出一些假设),但这是交易:

我认为您对信号和插槽机制的作用有些困惑。(或者可能不是,请原谅我重申了一些对你来说可能很明显的东西)。

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

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

Qt 中的信号和槽机制在 Qt 中的单个事件循环中运行(由 QApplication 实现),它本身在单个线程中运行。所以信号和槽无论如何都不能替代多线程。

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

因此,如果您有一个按钮,并且您想在单击请求库时开始下载文件,您会将clickedQPushButton 的信号连接到一个插槽,例如downloadButtonClicked,该插槽将启动一个新的 QThread注意使用请求下载文件。您可以进一步连接来自 QThread 的 finished() 信号,以了解下载何时完成并更新您的 UI

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

于 2013-10-21T12:45:47.937 回答