こんばんは、早速ですが質問させていただきます。
重いというよりかはCPUを占領しているのかもしれませんが、
for文内で、TLabelを再描画しようとしたのですが、うまくいきませんでした。
Formに ボタン、ラベルを貼り付けます。
ボタンの処理を
procedure TForm1.Button1Click(Sender: TObject);
var
i : Integer;
begin
for i := 0 to 100000 do
begin
Label1.Invalidate;
Label1.Caption := IntToStr(i);
end;
end;
このようにし、期待していた動作は、Labelのテキストが、増えていく経過が見れるようにしたかったのです。
しかし、結果はしばらく動かなくなり、いきなりLabelに100000と表示されてしまいます。
このような場合に再描画するのにはどうすればいいのでしょうか。
教えていただければ幸いです。
> Label1.Invalidate;
Application.ProcessMessages;
> Label1.Caption := IntToStr(i);
> Label1.Invalidate;
> Label1.Caption := IntToStr(i);
Label1.Update;
Label1.Update;よりも、ループ中にメッセージ処理が可能なApplication.ProcessMessages;の方がベター。
ProcessMessagesとUpdateの違いわかりますか?
Label1.Update;だけだとループが回っている間はフォームの移動もできないですよね?
Application.ProcessMessages; だとループが回ってるときでも Button1 をまた押せますけど..
> ループが回ってるときでも Button1 をまた押せますけど
procedure TForm1.Button1Click(Sender: TObject);
var
i : Integer;
begin
Button1.Enabled := False;
for i := 0 to 100000 do
begin
Label1.Invalidate;
Application.ProcessMessages;
Label1.Caption := IntToStr(i);
end;
Button1.Enabled := True;
end;
・・で良いのでは?
検証してないけど、これで二度押しは防げるかと。
目的次第でしょう ^^;
どちらでも「増えていく経過」は見れますが仕組みが違います。
ボタンの2度押しは防止するとして、
今回のような長いループは別のスレッドにしてもよさそうですね。
なるほど、このような場合には
Application.ProcessMessages;や、
UpDataを使うのですね。
とても参考になりました。
また、両者とも、用途に分けて使い分けていこうと思います。
(UpDataのほうが処理が速いなどのメリットがあればなのですが)
皆様多数の意見、参考になる発言をしていただきありがとうございました。
解決です
ツイート | ![]() |