表明应用程序正在做某事的最佳解决方案是什么?
我尝试显示进度指示器,但它没有用。
更新:-------------
进度条工作正常,但不是我想要的。
我希望展示一个throbber,就像网络浏览器使用的一样,所以只要有东西正在更新,它就会继续转动。
光标也可以处于crHourGlass模式。
答案 0 :(得分:8)
试试这个:
<强> AnimateUnit 强>
unit AnimateUnit;
interface
uses
Windows, Classes;
type
TFrameProc = procedure(const theFrame: ShortInt) of object;
TFrameThread = class(TThread)
private
{ Private declarations }
FFrameProc: TFrameProc;
FFrameValue: ShortInt;
procedure SynchedFrame();
protected
{ Protected declarations }
procedure Frame(const theFrame: ShortInt); virtual;
public
{ Public declarations }
constructor Create(theFrameProc: TFrameProc; CreateSuspended: Boolean = False); reintroduce; virtual;
end;
TAnimateThread = class(TFrameThread)
private
{ Private declarations }
protected
{ Protected declarations }
procedure Execute(); override;
public
{ Public declarations }
end;
var
AnimateThread: TAnimateThread;
implementation
{ TFrameThread }
constructor TFrameThread.Create(theFrameProc: TFrameProc; CreateSuspended: Boolean = False);
begin
inherited Create(CreateSuspended);
FreeOnTerminate := True;
FFrameProc := theFrameProc;
end;
procedure TFrameThread.SynchedFrame();
begin
if Assigned(FFrameProc) then FFrameProc(FFrameValue);
end;
procedure TFrameThread.Frame(const theFrame: ShortInt);
begin
FFrameValue := theFrame;
try
Sleep(0);
finally
Synchronize(SynchedFrame);
end;
end;
{ TAnimateThread }
procedure TAnimateThread.Execute();
var
I: ShortInt;
begin
while (not Self.Terminated) do
begin
Frame(0);
for I := 1 to 8 do
begin
if (not Self.Terminated) then
begin
Sleep(120);
Frame(I);
end;
end;
Frame(0);
end;
end;
end.
<强> 1单元强>
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls, ImgList;
type
TForm1 = class(TForm)
ImageList1: TImageList;
Image1: TImage;
Button1: TButton;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
procedure UpdateFrame(const theFrame: ShortInt);
end;
var
Form1: TForm1;
implementation
uses
AnimateUnit;
{$R *.DFM}
procedure TForm1.UpdateFrame(const theFrame: ShortInt);
begin
Image1.Picture.Bitmap.Handle := 0;
try
ImageList1.GetBitmap(theFrame, Image1.Picture.Bitmap);
finally
Image1.Update();
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
AnimateThread := TAnimateThread.Create(UpdateFrame);
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
AnimateThread.Terminate();
end;
end.
图片
答案 1 :(得分:6)
您可能正在主线程中运行耗时的任务。
一个选项是将其移动到后台线程,这将允许您的消息队列得到服务。您需要对其进行维护,以便您的进度条,甚至任何UI都能正常工作。
答案 2 :(得分:4)
回答更新后的问题:
答案 3 :(得分:1)
指标正常。更改后,您必须致电Application.ProcessMessages
。
答案 4 :(得分:0)
“表明该应用程序正在做某事的最佳解决方案是什么?” - 将鼠标光标设置为crHourGlass?或创建另一个表单/框架/ etc,注意用户应用程序正在“做”某事,他需要等待。
答案 5 :(得分:0)
从冗长的任务中,您偶尔可以更新视觉指示器,例如进度条或其他任何内容。但是,您需要通过在提供反馈的控件上调用Update
来立即重绘更改。
请勿使用Application.ProcessMessages
,因为这会引入可能的重入问题。