delphi 按钮在第二次移动时消失
delphi button vanishes when it moves for second time
我试图让一个按钮从 (0.0) 移动到 (500.500) 为此我使用了一个循环和一个线程睡眠过程,就像上面的代码一样:
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
前缀用于类型而不是实例。
作为一般准则,Sleep
永远不应在 UI 程序的主线程中调用。我不认为有很多(如果确实如此)例外。休眠会阻止 UI 线程为其消息队列提供服务。
我试图让一个按钮从 (0.0) 移动到 (500.500) 为此我使用了一个循环和一个线程睡眠过程,就像上面的代码一样:
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
前缀用于类型而不是实例。
作为一般准则,Sleep
永远不应在 UI 程序的主线程中调用。我不认为有很多(如果确实如此)例外。休眠会阻止 UI 线程为其消息队列提供服务。