如何在不冻结 GUI 的情况下在单个插槽中实现阻塞进程?

Posted

技术标签:

【中文标题】如何在不冻结 GUI 的情况下在单个插槽中实现阻塞进程?【英文标题】:How can I implement a blocking process in a single slot without freezing the GUI? 【发布时间】:2010-01-20 23:19:58 【问题描述】:

假设我有一个事件并且调用了相应的函数。此功能与外界交互,因此有时可能会有很长的延迟。如果函数等待或挂起,那么我的 UI 将冻结,这是不可取的。另一方面,必须将我的功能分解成许多部分并重新发出信号很长,并且可能会分解很多代码,这会导致难以调试和可读性降低,并且会减慢开发过程。事件驱动编程中是否有一个特殊功能可以让我只在一个函数调用中编写进程并能够让 mainThread 在等待时完成它的工作?例如,编译器可以识别一个关键字,然后实现一个返回,然后自动重新发出连接到新插槽的信号?为什么我认为这将是一个好主意;)我正在使用 Qt

【问题讨论】:

【参考方案1】:

您的两个选择是线程化,或者以某种方式分解您的功能。

使用线程,听起来您理想的解决方案是Qt::Concurrent。如果您的所有处理都已经在一个函数中,并且该函数非常独立(不引用类的成员变量),那么这很容易做到。如果没有,事情可能会变得更复杂一些。

为了分解你的函数,你可以按照你的建议去做,然后把它分解成不同的函数,不同的部分一个接一个地调用,或者你可以用一种更形象的方式来做,但是分散调用以允许函数内部的其他处理。我相信打电话给processEvents() 会做你想做的事,但我很久没有遇到过它的用途了。当然,除非您了解它可能会导致您的类的其他部分再次运行(以响应其他事件),否则您可能会遇到其他问题,因此您必须将它几乎视为多线程来保护变量在计算时处于不确定状态。

【讨论】:

processEvents() 听起来很有希望,我试试吧。谢谢。我一定要记住它可能带来的问题。【参考方案2】:

“事件驱动编程中是否有一个特殊功能,可以让我只在一个函数调用中编写进程,并且能够让 mainThread 在等待时完成它的工作?”

这将是一个非阻塞进程。

但您最初的查询是,“如何在不冻结 GUI 的情况下在单个插槽中实现阻塞进程?”

也许您正在寻找一种方法来在某些(任何)进程决定是时候阻止其他处理时停止其他处理?通常有很多方法可以做到这一点,是的,通过调用其中一个父对象的方法,当然,这取决于您正在使用的特定对象(例如框架)。

查看父对象,看看它们有哪些您想使用的方法。您可能需要覆盖其中一个才能获得您想要的结果。

【讨论】:

【参考方案3】:

如果您想通过开始长时间运行的任务来处理 GUI 事件,并且不希望 GUI 等待任务完成,您需要通过创建线程或新进程同时执行此操作执行任务。

如果任务是 I/O 绑定的并且偶尔回调来处理 I/O 就足够了,您可能可以避免创建线程或进程。我不熟悉 Qt 的主循环,但我知道 GTK 支持添加可以集成到 select()poll() 样式循环中的事件源,在超时或文件描述符准备好后运行处理程序。如果你有这样的任务,你可以让你的事件处理程序将这样一个事件源添加到应用程序的主循环中。

【讨论】:

以上是关于如何在不冻结 GUI 的情况下在单个插槽中实现阻塞进程?的主要内容,如果未能解决你的问题,请参考以下文章

如何在不重叠的情况下在 UIButton 中实现两个 IBAction?

如何在不中断删除的情况下在 SwiftUI 中实现 TextField 列表

在不移动数据的情况下在 CUDA 中实现 realloc

PyQt:如何在不冻结 GUI 的情况下更新进度?

如何在不冻结 GUI 的情况下使用视频帧不断更新 contentcontrol?

如何在没有像 Quartz Clustering 这样的集中式解决方案的情况下在分布式环境中实现 cron 作业/计划作业? [复制]