PyQt4:传统的多线程UI over Signal/Slot机制?

2024-10-01 04:56:20 发布

您现在位置:Python中文网/ 问答频道 /正文

有谁使用过多线程PyQt4应用程序?我只是想知道,与PyQt4框架的qtshread相结合的内置signal/slot机制是否比使用事件驱动异步回调的标准Python线程(在我的代码中,这些线程是以线程安全的方式处理UI组件的)相比是否有任何好处。在

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

谢谢。在

编辑:我意识到这可能意味着复制一些已经存在的PyQt核心功能,但如果它允许应用程序内更大的灵活性,也没关系。在


Tags: 代码框架应用程序ui标准signal方式组件
2条回答

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

如果你能澄清一下你的问题就好了,(因为这个问题我不得不做一些假设) 但交易是这样的:

我想你对信号和插槽机制的作用有点困惑。(或者也许没有,请原谅我重复了一些对你来说可能很明显的东西)。在

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

您可能假设signal slot机制是多线程的,当一个slot被信号调用时,它在一个新线程中执行。但事实并非如此。在

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

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

因此,如果你有一个按钮,并且你想在点击请求库时启动一个文件下载,你将把QPushButton的clicked信号连接到一个插槽,例如downloadButtonClicked,该插槽将启动一个新的QThread,该线程负责使用请求下载文件。您可以进一步从QThread连接finished()信号,以了解下载何时完成并更新UI

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

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

Sorry for the ambiguity, I was talking about QtThread Slot/Signal Mechanism vs. callbacks using inbuilt Python Threads. I intend on creating separate threads from UI on event arrival (clicks, etc) and then use callbacks to the main UI thread from the new threads to update the UI (all UI logic in the main thread with locks to keep it thread safe.) I know this might mean replicating some of the already present PyQt functionality but I feel this way I would have a lot more control over my app. (The extra work isn't a concern if it allows more flexibility in the app. Plus it isn't so much of work)

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

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

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

归根结底,我认为你的问题的答案只是个人喜好。我的建议是避免使用QThread,因为如果PyQt\PySide\Qt死了,将来将应用程序移植到另一个widget工具箱会更容易(虽然可能性不大,但我对PyGTK有过不好的体验,所以现在我很谨慎)

编辑:请再看看这个,因为它有比我给出的更好的答案:Threading in a PyQt application: Use Qt threads or Python threads?

相关问题 更多 >