如何在一个if语句中使程序休眠两次?

时间:2014-03-16 08:50:56

标签: delphi if-statement delphi-7 sleep

我想让一个程序在一个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;

2 个答案:

答案 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;