[英]How do I wait for a TTimer to finish?
I have a TFrame (fraDisplay) with a TTimer (timAnimateDataChange). 我有一个带有TTimer(timAnimateDataChange)的TFrame(fraDisplay)。 The timer is used to control a small animation.
计时器用于控制小动画。 In the form containing the frame I want to have a method that does something like this:
在包含框架的表单中,我希望有一个类似这样的方法:
procedure TForm.DoStuff;
begin
DoSomeLogicStuff;
fraDisplay.AnimateResult;
WaitForAnimationToFinish;
DoSomeOtherLogicStuff;
fraDisplay.AnimateEndResult;
WaitForAnimationToFinish;
fraDisplay.Finalize;
end;
The animations are basically redraws of a TImage32, timed by a timer. 动画基本上是由TImage32重绘,由计时器计时。 The timer will disable it self when finished, and the frame has a boolean property called AnimationRunning which will be set to false when the animation is finished.
完成时计时器将自动禁用它,并且帧具有名为AnimationRunning的布尔属性,当动画结束时,该属性将设置为false。
There are no threads or anything like that to complicate or help matters. 没有任何线索或类似的东西可以使事情变得复杂或有帮助。
The question is, how do I implement the WaitForAnimationToFinish-method? 问题是,我如何实现WaitForAnimationToFinish方法?
(Btw, this is not a good solution: (顺便说一句,这不是一个好的解决方案:
procedure TForm.WaitForAnimationToFinish;
begin
repeat
Application.ProcessMessages;
until not fraDisplay.AnimationRunning;
end;
since the timer won't fire while the method is running :-( ) 因为在方法运行时计时器不会触发:-()
Smasher's suggestion could be implemented using Delphi 2009's anonymous methods. Smasher的建议可以使用Delphi 2009的匿名方法实现。
procedure TForm.DoStuff;
begin
DoSomeLogicStuff;
fraDisplay.AnimateResult.OnFinished :=
procedure (Sender: TObject)
begin
DoSomeOtherLogicStuff;
fraDisplay.AnimateEndResult.OnFinished :=
procedure (Sender: TObject)
begin
fraDisplay.Finalize;
end;
fraDisplay.AnimateEndResult;
end;
fraDisplay.AnimateResult;
end;
BTW: Actually, WaitForAnimationToFinish will let OnTimer fire, since it uses windows messages that are dispatched when calling ProcessMessages. BTW:实际上,WaitForAnimationToFinish会让OnTimer激活,因为它使用在调用ProcessMessages时调度的Windows消息。 But it is a bad idea anyway since it uses lots of CPU without actually needing it.
但无论如何它都是一个坏主意,因为它使用了大量的CPU而实际上并不需要它。
当计时器禁用自身并将AnimationRunning
变量设置为False
,您可以调用下一个应该执行的方法。
斯洛文尼亚的Delphi程序员只写了你正在寻找的代码 - Active Sleep 。
So what your timer is doing is something lengthy, on the order of several seconds? 那么你的计时器正在做什么是长时间的,大约几秒钟? That kind of long-running activity shouldn't be performed in the main GUI loop anyway.
无论如何,不应该在主GUI循环中执行那种长时间运行的活动。 Nor should waiting for such:
也不应该等待:
While you're waiting for the animation to finish (if you could), the rest of your application will behave like a dead program, ie it will not respond to the GUI in any way, including resizing, redrawing, closing with the X , etc. 当你等待动画完成时(如果可以的话),你的应用程序的其余部分将表现得像死程序,即它不会以任何方式响应GUI,包括调整大小,重绘,用X关闭,等等
The solution is to instead break up your DoStuff method into two; 解决方案是将DoStuff方法分解为两个; one that starts up the timer activity, and a second one that executes when the timer finishes.
一个启动计时器活动,另一个启动计时器完成。 To accomplish the latter, that timer should be calling your second method just before saying goodbye.
要完成后者,那个计时器应该在说再见之前调用你的第二种方法。
Lars has done a great job of putting together an example; 拉斯在组织榜样方面做得很好; consider this the book to go with his movie :)
考虑这本书与他的电影:)
使AnimateResults在完成后调用要调用的方法的参数。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.