【问题标题】:How do I avoid flicker in my application?如何避免在我的应用程序中闪烁?
【发布时间】:2013-01-12 11:52:43
【问题描述】:

这是每个开发人员时不时面临的一个非常常见的问题,因为视觉更新可能如此快速和快速,以至于导致表单内容闪烁。我目前正在使用一个线程来搜索文件并触发一个事件到它的调用(主 VCL)线程来报告每个搜索结果。如果您曾经使用过FindFirst / FindNext,或者为此执行过非常快速且快速的迭代的任何大型循环,那么您就会知道在每次小迭代中更新 GUI 非常繁重,并且几乎失败线程的目的,因为线程随后取决于 GUI 更新的速度(在线程内的每次迭代中)。

我对来自线程的每个事件(1 毫秒内可能有 100 个事件)所做的只是增加一个全局整数,以计算迭代次数。然后,我在主窗体的标签中显示该数字。可以想象,来自线程的快速更新会导致闪烁失控。

所以我想知道的是,当线程向其提供事件的速度超过其能够更新的速度时,如何避免 GUI 中的这种快速闪烁?

注意:我使用的是 VCL 样式,所以闪烁变得更糟。

【问题讨论】:

  • 窗口化静态控件,TStaticText,不会像 TLabel 那样闪烁。

标签: multithreading delphi user-interface iteration flicker


【解决方案1】:

这确实是一个常见问题,并非总是由线程引起,而是由任何需要更新 GUI 的循环引起,同时循环的迭代速度快于 GUI 能够更新的速度。快速简便的解决方案是使用计时器来更新您的 GUI。每当循环触发更新时,不要立即更新 GUI。相反,为每个可能需要更新的东西(显示计数的标签)设置一个全局变量(如全局迭代计数),然后让计时器进行 GUI 更新。将计时器的间隔设置为 100-200 毫秒。这样,您可以控制 GUI 更新的频率与您设置的计时器间隔一样频繁。

这样做的另一个好处是您的线程性能将不再取决于您的 GUI 更新速度。线程可以触发它的事件并且只增加这个整数,然后继续它的工作。请记住,您仍然必须确保对 GUI 进行线程保护。这是一门艺术,我不会介绍它,假设你已经知道了。

注意:您需要执行的 GUI 更新越多,您可能需要调整计时器的间隔就越高。

【讨论】:

  • 不仅仅是闪烁是问题。还要考虑一下,即使 smoothly(不闪烁),用户会从一个标签中得到什么,它会显示一个每秒变化 100000 次的值。 [+1]
  • 是的,这也是减慢速度的问题的一部分,这就是为什么我在问题中提到“破坏线程的目的”
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-02
  • 1970-01-01
  • 2013-05-02
  • 1970-01-01
  • 2016-07-18
  • 1970-01-01
相关资源
最近更新 更多