0

我正在尝试Label01 Font Color使用Timer04. 我的要求是将字体颜色的十进制值从0增加到16777215。当字体颜色达到16777215时,它会再次减少到0。这将是一个连续的循环。如果基本三种颜色(* RGB )的增量和减量比例相同,则只有从黑到白,从白到黑。所以我定义了以下代码:

procedure TMainForm.Timer04Timer(Sender: TObject);
var
  RedColor, GreenColor, BlueColor: integer;
begin
  RedColor := 1;
  GreenColor := 2;
  BlueColor := 3;
  if (RedColor >= 1) and (RedColor <= 255) then RedColor := RedColor + 5;
  if (GreenColor >= 1) and (RedColor <= 255) then GreenColor := GreenColor + 5;
  if (BlueColor >= 1) and (BlueColor <= 255) then BlueColor := BlueColor + 5;
  Label01.Font.Color := RedColor + GreenColor + BlueColor;
end;
..
..
..
..
..
procedure TMainForm.FormCreate(Sender: TObject);
begin
  Timer04.Enabled := true;
end;

但事实并非如此。只有黑色是可见的。

4

2 回答 2

5

每次计时器经过Timer04Timer并被调用时,您总是用相同的颜色初始化局部变量,因此生成的 TLabel 颜色总是相同的。您需要使用 TLabel 的当前颜色来初始化变量,例如:

procedure TMainForm.Timer04Timer(Sender: TObject);
var
  CurrentColor, RedColor, GreenColor, BlueColor: integer;
begin
  CurrentColor := ColorToRGB(Label01.Font.Color);

  RedColor := GetRValue(CurrentColor);
  GreenColor := GetGValue(CurrentColor);
  BlueColor := GetBValue(CurrentColor);

  // manipulate R, G, B as needed...

  Label01.Font.Color := RGB(RedColor, GreenColor, BlueColor);
end;

procedure TMainForm.FormCreate(Sender: TObject);
begin
  Label01.Font.Color := clBlack;
  Timer04.Enabled := true;
end;
于 2013-07-18T17:00:30.427 回答
2

但是在过程之外采取一些外部位置来保存您的值 - 因为局部变量在过程退出后不存在(并且其中的值丢失)(否则递归和多线程将是不可能的)

type
  TMainForm = class(TForm)
  ....
  private 
    Luminosity: byte;
    Direction:  shortint; 
  end;

// Those variables exist in the form itself, outside of 
//   the procedure, thus can be used to hold the values you need.

procedure TMainForm.Timer04Timer(Sender: TObject);
begin
  Label01.Font.Color := RGB(Luminosity, Luminosity, Luminosity);

  if ((Luminosity =   0) and (Direction < 0)) or 
     ((Luminosity = 255) and (Direction > 0)) 
  then Direction := - Direction // go back
  else Luminosity := Luminosity + Direction; // go forth
end;

procedure TMainForm.FormCreate(Sender: TObject);
begin
  Luminosity := 0;
  Direction := +1;
  Timer04.Enabled := true; 
end;

变量是表单本身的成员,因此它们存在于过程之外,因此可用于在过程退出后保留值。


PS。上面在颜色摆动范围的末端有一个稍微明显的延迟(它通过更改符号而不是更改颜色来跳过一个“计数”)。如果我为我的项目这样做,我会增加额外的延迟(通过额外的计数器或通过调整计时器属性),所以用户会真正看到颜色停留一段时间(并给他一些时间以相对舒适的方式阅读文本)。这不是任务所要求的,但它会使恕我直言的用户体验更好。

type
  TMainForm = class(TForm)
  ....
  private 
    var
      Luminosity, Latch: byte;
      Direction:  shortint; 
    const 
      LatchInit = 5;
  end;

// Those variables exist in the form itself, outside of 
//   the procedure, thus can be used to hold the values you need.

procedure TMainForm.TimerLabelColorTimer(Sender: TObject);
begin
  if Latch > 0 then begin
     Dec(Latch);
     exit;  
  end;

  LabelSwinging.Font.Color := RGB(Luminosity, Luminosity, Luminosity);

  if ((Luminosity =   0) and (Direction < 0)) or 
     ((Luminosity = 255) and (Direction > 0)) 
  then begin 
     Direction := - Direction; // go back
     Latch := LatchInit;       // give user eyes time to relax
  end else 
     Luminosity := Luminosity + Direction; // go forth
end;

procedure TMainForm.FormCreate(Sender: TObject);
begin
  Luminosity := 0;  // optional: Delphi objects  anyway do zero their internal
  Latch := 0;       //    variables before entering the constructor

  Direction := +1;  // and that is required
end;

procedure TMainForm.FormShow(Sender: TObject);
begin
  TimerLabelColor.Enabled := true; 
end;

procedure TMainForm.FormHide(Sender: TObject);
begin
  TimerLabelColor.Enabled := false;
end;

启用计时器在处理程序中没有位置,OnCreate原因有两个:

  • 您可以通过更改 IDE 对象检查器中的属性将您想要的OnCreate内容放入 DFM
  • 更重要的是 - 在不可见的表单上更改标签颜色几乎没有意义,因此创建表单有点为时过早,无法启动计时器序列。
于 2013-07-18T17:01:13.707 回答