【问题标题】:Delphi - how to move a control and refresh itDelphi - 如何移动控件并刷新它
【发布时间】:2011-05-26 14:26:31
【问题描述】:

对于 Delphi 中的编程练习,我想一次在屏幕上滚动一个图像 1 个像素,并在每次移动它时重新绘制它,所以它看起来实际上是在移动。目前 Delphi 只是在开始和结束时绘制它,所以它并不平滑。我尝试了重绘和刷新,但都没有奏效。我还尝试让它可见和不可见,看看是否可行,但没有运气。

image1.Visible := true;
for i := 0 to 50 do
begin
   image1.Visible := false;
   image1.Left := image1.Left + 1;
   image1.Repaint(); // this doesn't work...
   for j := 0 to 1000000 do
   begin
      k := i + j; // do nothing code
   end; 
   image1.Visible := true;
end;

有人知道我错过了什么吗?谢谢。

【问题讨论】:

  • 说丑:busy-loop 不缺。

标签: delphi


【解决方案1】:

一个更好的方法是使用计时器。在 Delphi 中,这意味着 TTimer 类的对象。每次计时器触发时,您只需增加 Left 属性。您可能需要一个计数器,一旦它触发了您想要的次数,它就会禁用计时器。

【讨论】:

  • +1 我刚刚将此添加到我上面的评论中。而且,最重要的是,您不应该通过移动视觉控件来制作动画!
【解决方案2】:
procedure TForm1.FormClick(Sender: TObject);
var
  i: integer;
begin
  for i := 0 to 50 do
  begin
    image1.Left := image1.Left + 1;
    Application.ProcessMessages;
    sleep(100);
  end;
end;

您也可以使用Image1.Update 代替Application.ProcessMessages,但随后应用程序将停止响应Windows 消息;因此,它会“冻结”。无论如何,这是一种非常丑陋的动画制作方式(非常丑陋!),但如果它只是一个练习,那么......

【讨论】:

  • 谢谢。这行得通。我知道它会闪烁并且看起来很难看,但那是 Windows。
  • @Thomas O:不,那不是 Windows。这只是糟糕的编程......(对不起......)如果你真的想做动画,你应该手动完成所有绘图(使用 GDI),而不仅仅是移动可视 VCL 控件!此外,您应该使用双缓冲。如果需要更高级的渲染,可以使用 OpenGL。我在 Delphi 中做了很多 3D 图形和动画。有关一些示例,请参见 www.algosim.se。此外,动画中的触发事件应该是计时器消息的一部分,而不是 for 循环。这将以某种方式冻结应用程序。 (尝试在图像移动时关闭窗口。)
  • @Thomas O:这是错误的,原因很多,不仅仅是闪烁。例如,像这样处理消息不是一个好主意。如果您从该 Onclick 内部收到另一个 OnClick,是相同的还是用于不同动画的呢?如果你得到 WM_QUIT 并且你的应用程序在 OnClick 中终止了怎么办?还是活动表单被关闭并销毁?
  • @Thomas O SP3 就是一个服务包。他们修复错误并关闭安全漏洞。他们不会重新设计操作系统。 Vista 引入了一个全新的渲染引擎,这是一个巨大的改进。
  • 我认为重要的是要指出,增加变量以模拟延迟的 for 循环也不是一个好主意。每台 PC 上的延迟可能会有所不同。让我想起了当我在 486 上以 33MHz 运行一个类似俄罗斯方块的旧游戏,然后在几年后再次找到它时在 Pentium 上运行它,它无法播放,因为它运行速度快了大约 10 倍:-)
猜你喜欢
  • 2019-02-06
  • 2019-10-17
  • 2014-02-18
  • 2017-03-16
  • 2020-04-02
  • 1970-01-01
  • 2010-12-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多