0

Label01 Font Colorを使って変更しようとしてTimer04います。私の要件は、フォントの色の 10 進値を0から16777215に増やすことです。フォントの色が16777215に達すると、同じ色が再び0に減少します。連続ループになります。基本 3 色 (* 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。上記の色スイング範囲の端でわずかに目立つ遅延があります (色を変更する代わりに符号を変更することにより、1 つの「カウント」をスキップします)。私が自分のプロジェクトでそれを行った場合、(カウンターを追加するか、タイマーのプロパティを微調整することで) さらに遅延を追加したため、ユーザーはその色がしばらくの間スタックしているのを実際に見ることができます (そして、比較的快適にテキストを読むための時間を与えることができます)。 )。これはタスクによって必須ではありませんが、IMHO ユーザー エクスペリエンスが向上します。

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次の 2 つの理由から、ハンドラーで行う場所がありません。

  • IDE の Object Inspector でプロパティを変更することにより、必要なものOnCreateを DFM に入れることができます。
  • さらに重要なことは、目に見えないフォームのラベルの色を変更する意味がほとんどないため、タイマー シーケンスを開始するにはフォームの作成が少し早すぎることです。
于 2013-07-18T17:01:13.707 に答える