表明应用程序正在做某事的最佳解决方案是什么?
我尝试显示进度指示器,但它不起作用。
更新: - - - - - - -
进度条工作正常,但不是我想要的。
我想展示一个throbber,就像 Web 浏览器使用的一样,所以只要有东西在更新,它就一直在转动。
光标也可以处于 crHourGlass 模式。
表明应用程序正在做某事的最佳解决方案是什么?
我尝试显示进度指示器,但它不起作用。
更新: - - - - - - -
进度条工作正常,但不是我想要的。
我想展示一个throbber,就像 Web 浏览器使用的一样,所以只要有东西在更新,它就一直在转动。
光标也可以处于 crHourGlass 模式。
试试这个:
动画单元
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.
图片
您可能正在主线程中运行耗时的任务。
一种选择是将其移动到允许为您的消息队列提供服务的后台线程。您需要对其进行维护,以使您的进度条以及任何 UI 都能正常工作。
回答更新的问题:
一个指标OK。更改后必须调用Application.ProcessMessages
。
“表明该应用程序正在做某事的最佳解决方案是什么?” - 将鼠标光标设置为 crHourGlass?或创建另一个表单/框架/等来提醒用户应用程序正在“做”某事,他需要等待。
从您的冗长任务中,您偶尔可以更新视觉指示器,例如进度条或其他任何内容。Update
但是,您需要通过调用提供反馈的控件立即重绘更改。
不要使用Application.ProcessMessages
,因为这会引入可能的重入问题。