代码之家  ›  专栏  ›  技术社区  ›  User049

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

  •  3
  • User049  · 技术社区  · 11 年前

    我想让一个程序一次两次等待几秒钟 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 回复  |  直到 11 年前
        1
  •  7
  •   NGLN Selim Serhat Çelik    11 年前

    第二个 Sleep 未跳过;您将看到您在7秒内无法移动表单。

    具有 睡觉 您使应用程序无响应,以至于它没有时间更新自己。设置形状的颜色会请求父窗口再次绘制形状(使用新的颜色设置),但这些绘制请求不会被处理,因为您暂停了应用程序。这两种颜色的改变都被重新处理,但两种绘画请求都被打包成一种,只剩下后者能持久。

    一种简单的方法是在以下两种情况之间自行更新表单:

    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 消除使用 睡觉 全部加在一起:

    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)变量来决定应设置哪些颜色和间隔。

        2
  •  2
  •   LU RD    11 年前

    程序流是事件驱动的。用 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;