Delphi palpitante
-
27-10-2019 - |
Pregunta
¿Cuál es la mejor solución para mostrar que la aplicación está haciendo algo?
Intenté mostrar un indicador de progreso, pero no funcionó.
ACTUALIZAR: -------------
Una barra de progreso funciona bien, pero no es lo que quiero.
Quiero mostrar un palpitán, como lo que usan los navegadores web, por lo que mientras se actualice algo, sigue girando.
El cursor también puede estar en modo crhourglass.
Solución
Prueba esto:
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.
Unidad 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.
Las imagenes
Otros consejos
Probablemente esté ejecutando su tarea que consume mucho tiempo en el hilo principal.
Una opción es moverlo a un hilo de fondo que permitirá que su cola de mensajes sea reparada. Necesita que sea reparado para que su barra de progreso y, de hecho, cualquier interfaz de usuario, funcione.
Respuesta a la pregunta actualizada:
- Generar un gif animado, por ejemplo, aquí
- Agregue una biblioteca GIF a su entorno (Jedi JVCL+JCL)
- Inserte un M venicio y cargue el GIF generado
- Hazlo visible si lo necesitas
Un indicador está bien. Tienes que llamar Application.ProcessMessages
Después de cambiarlo.
Update
Sobre el control que proporciona la retroalimentación.
No lo usas Application.ProcessMessages
ya que esto introducirá posibles problemas de reingreso.