Delphi throbber
-
27-10-2019 - |
Question
Quelle est la meilleure solution pour montrer que l'application est en train de faire quelque chose?
J'ai essayé montrant un indicateur de progression, mais il ne fonctionne pas.
MISE À JOUR: -------------
travaux de barre de progression bien, mais est pas ce que je veux.
Je veux montrer un throbber , comme ce que les navigateurs Web utilisent, aussi longtemps que quelque chose est mise à jour, il continue à tourner.
Le curseur peut également être en mode crHourGlass.
La solution
Essayez ceci:
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.
part1
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.
Les images
Autres conseils
Vous utilisez probablement votre temps tâche dans le thread principal.
L'une des options est de le déplacer à un fil d'arrière-plan qui permettra à votre file d'attente de messages à desservir. Vous avez besoin d'être réparé pour que votre barre de progression, et en fait une interface utilisateur, au travail.
indicateur A est OK. Vous devez appeler Application.ProcessMessages
après l'avoir modifié.
« Quelle est la meilleure solution pour montrer que cette application est en train de faire quelque chose? » - Placer le curseur de la souris pour crHourGlass? ou créer une autre forme / châssis / etc qui attention l'utilisateur que l'application est « faire » quelque chose, et il a besoin d'attendre.
De votre tâche longue, vous pouvez mettre à jour de temps en temps un indicateur visuel, comme une barre de progression ou toute autre chose. Cependant, vous devez redessiner les changements immédiatement en appelant Update
sur le contrôle qui fournit les commentaires.
Ne pas utiliser Application.ProcessMessages
car cela introduira les éventuels problèmes de réentrée.