2011-04-29 111 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,因爲這會引入可能的重入問題。