我想让一个程序在一个if
语句中等待几秒钟。但我的问题是它跳过了第二个Sleep
命令?我找了一个答案,但似乎没有其他人有这个?
procedure TForm1.BitBtn1Click(Sender: TObject);
begin
if Form1.shapeGreen.Brush.Color=clLime then
begin
Sleep(4000);
Form1.shapeRed.Brush.Color:=clMaroon ;
Form1.shapeYellow.Brush.Color:=clYellow;
Form1.shapeGreen.Brush.Color:=clGreen;
Sleep(3000); (it skips this (waits 0...))
Form1.shapeRed.Brush.Color:=clRed ;
Form1.shapeYellow.Brush.Color:=clOlive;
Form1.shapeGreen.Brush.Color:=clGreen;
end;
end;
答案 0 :(得分:7)
不跳过第二个Sleep
;你会发现你无法移动你的表格7秒钟。
使用Sleep
,您可以使应用程序无响应,以至于没有时间自行更新。设置形状的颜色要求父级窗口再次绘制形状(使用新的颜色设置),但不处理这些绘制请求,因为您暂停应用程序。两种颜色变化都得到了处理,但两个颜色变化请求都被打包成一个,只留下后者才能使用。
一种简单的方法是在两者之间自己更新表单:
procedure TForm1.BitBtn1Click(Sender: TObject);
begin
if ShapeGreen.Brush.Color = clLime then
begin
Sleep(4000);
ShapeRed.Brush.Color := clMaroon;
ShapeYellow.Brush.Color := clYellow;
ShapeGreen.Brush.Color := clGreen;
Update;
Sleep(3000);
ShapeRed.Brush.Color := clRed;
ShapeYellow.Brush.Color := clOlive;
ShapeGreen.Brush.Color := clGreen;
end;
end;
但这仍然会使您的应用程序冻结两次。 (请注意,在暂停期间,您无法在应用程序中执行任何操作)。更好的解决方案是使用Timer
来消除所有Sleep
的使用:
procedure TForm1.BitBtn1Click(Sender: TObject);
begin
if ShapeGreen.Brush.Color = clLime then
begin
Timer1.Interval := 4000;
Timer1.Enabled := True;
end;
end;
procedure TForm1.Timer1Timer(Sender: TObject);
begin
if ShapeGreen.Brush.Color = clLime then
begin
ShapeRed.Brush.Color := clMaroon;
ShapeYellow.Brush.Color := clYellow;
ShapeGreen.Brush.Color := clGreen;
Timer1.Interval := 3000;
end
else
begin
ShapeRed.Brush.Color := clRed;
ShapeYellow.Brush.Color := clOlive;
Timer1.Enabled := False;
end;
end;
下一步是使这段代码中的逻辑更加简洁,例如用(a)变量决定应该设置哪些颜色和间隔。
答案 1 :(得分:2)
程序流程是事件驱动的。通过Sleep()
调用打破流程将使您的应用程序无响应。在您的情况下,它将阻止在第一步中更新颜色。因此,它似乎正在跳过最后Sleep()
次呼叫。
使用Timer
和状态变量来改变给定时间间隔的颜色。
Type
TMyState = (msActivate,msFirstStep,msSecondStep);
Tform1 = class(TForm)
...
private
fMyCounter: Integer;
fMyState : TMyState;
end;
// Timer1 is a TTimer with interval 1000 ms,
// initially disabled
procedure TForm1.Timer1Timer(Sender: TObject);
begin
Inc(fMyCounter);
case fMyState of
msActivate:
begin
fMyCounter := 0;
fMyState := msFirstState;
end;
msFirstState:
if (fMyCounter = 4) then
begin
ShapeRed.Brush.Color := clMaroon;
ShapeYellow.Brush.Color := clYellow;
ShapeGreen.Brush.Color := clGreen;
fMyState := msSecondState;
fMyCounter := 0;
end;
msSecondState:
if (fMyCounter = 3) then
begin
ShapeRed.Brush.Color := clRed;
ShapeYellow.Brush.Color := clOlive;
ShapeGreen.Brush.Color := clGreen;
Timer1.Enabled := False;
end;
end;
end;
procedure TForm1.BitBtn1Click(Sender: TObject);
begin
if shapeGreen.Brush.Color=clLime then
begin
fMyState := msActivate;
Timer1.Enabled := True; // Trigger color change states
end;
end;