【发布时间】:2017-09-01 10:46:26
【问题描述】:
有很多关于在 GUI 中旋转或移动繁忙指示器的讨论(例如 here),但我找不到一个明确指出不可能重新绘制/更新任何内容的讨论主线程被阻塞时的 GUI 应用程序。
这个问题其实是一个笼统的问题,不一定和Qt GUI应用直接相关。
当 GUI 的主线程正在执行阻塞操作时,不会处理任何事件,也不会重新绘制任何内容。有两种“推荐”的方法:
- 使用工作线程
- 分块工作并“不那么频繁”更新 UI
问题在于,有些操作根本无法移至工作线程或任何其他异步机制。最好的例子是 UI 本身的序列化和反序列化。在这两种情况下,用户不得在 UI 中愉快地单击并更改设置,而设置、属性等从小部件中获取(在保存期间)或应用于小部件(在加载期间)。这对于线程方法以及分割成块都是正确的。 编辑: 另一个例子是将样式表应用于完整的 GUI。想象一下,用户想要选择一个“暗”方案。所有小部件都需要更新,当前可见的小部件需要重新绘制。在此步骤期间,事件循环无法运行。类似的讨论可以在here找到。
就我而言,我正在使用嵌入式设备,所以还有另一种方法:
- 直接覆盖帧缓冲区的特定区域
这种方法感觉很丑陋,会带来很多有问题的场景,而且还需要大量的调试。
最后但悲伤的方法:
- 根本不使用任何移动/更新内容,只显示静态内容,例如“...进行中...”
好吧,这只是悲伤......
您同意这些意见吗?有谁知道通常与 Qt 无关的不同方法或概念?
【问题讨论】:
-
我不确定与 Qt 无关的一般情况,但 Qt 中有
processEvents函数可以满足您的需求。 -
processEvents重新进入事件循环,是不必要的。如果你可以使用processEvents,你已经可以分块操作了。 -
这个问题太宽泛了,是 XY 问题的一个糟糕案例。您正在讨论具体解决方案,而没有详细描述您正在解决的具体问题。如果您具体地询问如何以提供良好用户体验的异步方式很好地反序列化 UI - 只需询问这个问题,而不是询问一些定义不明确的“一般”问题需要涵盖十几个单独的问题。 您遇到问题的特定场景是什么?确切地说反序列化:每个人在使用该术语时都意味着 10 种不同的东西。
-
@KubaOber:感谢您的回复。你似乎真的不喜欢我的问题和我问的风格。我描述的是一个场景,也许我的例子并不完美,但这个场景只是存在。只需将其作为您需要解决的数学问题的描述您无法更改其描述:-) 这个问题是关于 GUI 编程概念的。当然它有点宽泛:-)
-
@BeardedBeaver:感谢您的回复,但 processEvents 并没有做我想要的。它只是推动事件循环的执行,这是不推荐的,此外也不能解决问题。当您有较长的操作在 Qt 本身(或 GUI 框架本身)中执行慢速操作时,您无法调用 processEvents,没有可以拦截的“块”(正如 Kuba Ober 指出的那样)。
标签: qt user-interface busyindicator