delphi按钮第二次移动时消失

标签 delphi button delphi-xe8

我正在尝试使按钮从 (0.0) 移动到 (500.500),因为我使用了循环和线程 sleep 过程,如上面的代码所示:

       unit Unit1;

       interface

       uses
       Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
       Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

       type
       TForm1 = class(TForm)
          TbuttonAction: TButton;
          procedure show(Sender: TObject);
        private
         { Déclarations privées }
        public
         { Déclarations publiques }
        end;

        var
         Form1: TForm1;

       implementation

        {$R *.dfm}

       procedure TForm1.show(Sender: TObject);
        var
          i: Integer;
        begin
          TbuttonAction.Caption:='my first action';

          for i := 0 to 500 do
            begin

                 TThread.Sleep(10);
                 TbuttonAction.Top:=i;
                 TbuttonAction.Left:=i;

                end;
               end;
           end.

第一次单击时,按钮从 0.0 移动到 500.500,但如果我单击另一次(当按钮位于 500.500 时第二次或第三次),按钮会消失,然后在一段时间后出现。请问如何解决这个问题?我今天开始使用 Delphi,但我对 Java 很有经验(3 年)。

最佳答案

发生这种情况大概是因为您没有抽动消息队列。 Windows 应用程序需要主 UI 线程及时为其消息队列提供服务,以便可以处理绘画和输入等事务。您用繁忙的循环阻塞了主线程。

删除循环并添加计时器。计时器通过消息循环生成的消息进行操作,因此不会阻塞主 UI 线程。

给定时器一个适当的间隔,比如100ms。当您想要开始动画时,请将计时器的 Enabled 属性设置为 True

procedure TForm1.Show(Sender: TObject);
begin
  Button1.Left := 0;
  Button1.Top := 0;
  Timer1.Interval := 100;
  Timer1.Enabled := True;
end;

像这样实现计时器的 OnTimer 事件:

procedure TForm1.Timer1Timer(Sender: TObject);
var
  Pos: Integer;
begin
  Pos := Button1.Left + 10;
  Button1.Left := Pos;
  Button1.Top := Pos;
  if Pos >= 500 then
    Timer1.Enabled := False;
end;

我重命名了你的按钮。 T 前缀用于类型而不是实例。

作为一个广泛的指导原则,永远不应该在 UI 程序的主线程中调用 Sleep。我认为,如果确实有的话,也不会有很多异常(exception)。休眠会阻止 UI 线程为其消息队列提供服务。

关于delphi按钮第二次移动时消失,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32414732/

相关文章:

delphi - 如何仅通过知道其句柄来确定 Canvas 尺寸?

delphi - 在 Delphi XE2 上安装 DWScript 时必须重新编译“designide”

delphi - 使用 poUnbuffered 时 TVirtualStringTree 中的 PaintTree 行为不正确

multithreading - Delphi 线程与 TRestRequest

Android:如何创建一个图像和文本都居中的按钮

image - 如何更改点击Unity时的按钮图像

android - DELPHI中如何检测设备是否有硬件BACK和MENU键

css - 带有图像的 JavaFX CSS 按钮 - 如何定义图像的大小?

delphi - 当我尝试安装 Delphi-OpenCV。我得到 "%1 is not a valid Win32 application. "

delphi - 在非Windows平台上刷新文件缓冲区