2011-04-29 97 views
2

什么是最好的解决方案来表明应用程序正在做什么?德尔菲跳动

我试着显示一个进度指示器,但没有奏效。

更新:-------------

一个进度条,工作正常,但不是我想要的。

我想展示一个throbber,就像Web浏览器使用的一样,只要有东西在更新,它就会一直转动。

光标也可以在crHourGlass模式。

+2

“没有工作”是不准确的。它是如何工作的?你的两个答案已经做出了相同的假设,为什么它不起作用,但我们可能是错的! – 2011-04-29 10:55:52

+0

你正在寻找的词是* throbber *,所以我将它添加到你的问题中。你仍然需要告诉我们,当你说你的“进度指示器”不起作用时,你是在说什么,然后你需要说出发生了什么,以及你期望发生什么。 – 2011-04-29 12:34:41

+0

是的。我生成图像,但可以看到它移动... – DRokie 2011-04-29 12:43:57

回答

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. 

的图像

image1 image2 image3 image4 image5 image6 image7image8

animate1

+0

这很有趣......只要能正确地获取图像,你可以将这些图像发送给我吗?谢谢。 – DRokie 2011-04-29 20:56:01

+0

你可以在这里下载:http://www.eyeclaxton.com/download/images.zip – eyeClaxton 2011-04-30 00:02:37

1

指标正常。更改后必须致电Application.ProcessMessages

+7

请不要。改用“ProgressBar.Update”。 'Application.ProcessMessages'有很多你需要处理的潜在问题;只是调用控件的'更新'就可以做到你想要做的事情,速度更快,并且没有任何问题。 – 2011-04-29 11:03:35

+2

@ Ken真的,但其余的UI也会死掉。当区域无效时,它不会重新绘制。取消按钮(如果存在)将不起作用。等等。如果您要在主线程中运行长时间运行的任务(并且理想情况下您不会),那么实现它的唯一方法就是ProcessMessages,并带来所有后果。 – 2011-04-29 11:17:37

+0

@Ken:我与大卫同意。我知道差异和缺点,但恕我直言作为一个简单的解决方案的新手这是最好的方式去。 – 2011-04-29 11:25:38

6

您可能正在主线程中运行耗时的任务。

一种选择是将其移动到后台线程,这将允许您的消息队列被服务。您需要对其进行维护,以便使您的进度条以及任何UI都能正常工作。 “

0

”什么是最好的解决方案,以表明该应用程序正在做什么?“ - 将鼠标光标设置为crHourGlass?或者创建另一个表单/框架/等,它们会关注用户应用程序正在“做”的事情,而且他需要等待。

4

回答到更新的问题:

  • 生成动画GIF例如here
  • 添加GIF库环境(JEDI JVCL + JCL)
  • 插入的TImage和加载生成GIF
  • 使其可见,如果你需要它
+0

即使另一个线程被冻结,动画GIF也会保持“跳动”。 OP要求一个跳动者,他必须ping更新。 – 2011-04-29 15:09:15

+0

为动画GIF网站+1。 – 2011-04-29 21:32:59

0

从冗长的任务中,您可以偶尔更新视觉指示器,如进度条或其他任何东西。但是,您需要通过在提供反馈的控件上调用Update来立即重绘更改。

请勿使用Application.ProcessMessages,因为这会引入可能的重入问题。