我如何避免应用程序中的闪烁?

3
这是每个开发人员时不时都会遇到的常见问题,当视觉更新非常快时,会导致表单内容闪烁。我目前正在使用一个线程来搜索文件并触发事件,以便调用(主VCL)线程报告每一个搜索结果。如果您曾经使用过FindFirst / FindNext,或者进行了任何大型循环,这些循环执行非常快且迅速的迭代,那么您就会知道在每个小迭代中更新GUI非常沉重,几乎打败了线程的目的,因为线程随后变得取决于GUI可以多快地更新(在线程内的每个迭代中)。
每次从线程触发事件时(1毫秒内可能有100个事件),我所做的就是简单地增加全局整数,以计算迭代次数。然后,我将该数字显示在主窗体上的标签中。正如您所想象的那样,来自线程的快速更新将导致它无法控制地闪烁。
那么,我想知道的是如何避免当线程向GUI提供事件的速度比其更新速度快时,GUI的快速闪烁?
注意:我正在使用VCL样式,因此闪烁会变得更糟。

窗口静态控件(Windowed static controls),即TStaticText,不会像TLabel控件那样闪烁。 - David Heffernan
1个回答

4
这确实是一个常见的问题,不仅仅是在线程中,任何需要更新GUI并且循环速度比GUI更新速度快的循环都会出现这个问题。解决这个问题的快捷而简单的方法是使用Timer来更新GUI。每当循环触发更新时,不要立即更新GUI。相反,为可能需要更新的每个元素(如显示计数的标签)设置一些全局变量(如全局迭代计数),然后让计时器执行GUI更新。将计时器的间隔设置为100-200毫秒。这样,您可以控制GUI更新仅在设置计时器间隔的频率下发生。
另一个好处是,您的线程性能不再取决于GUI更新的速度。线程可以触发其事件并仅递增此整数,然后继续工作。请记住,您仍然必须确保对GUI进行线程保护。这是一门艺术,我不会涉及,假设您已经了解了。
注意:您需要执行的GUI更新越多,您可能需要调整计时器的间隔就越高。

不仅仅是闪烁问题。还要考虑一下,如果一个标签即使没有闪烁,但每秒变化100000次的值,对用户来说有什么意义。【+1】 - TLama
是的,这也是减慢速度的问题之一,这就是为什么我在问题中提到了“打败线程的目的”的原因。 - Jerry Dodge

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接