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.

¿Fue útil?

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

image1 image2 image3 image4 image5 image6 image7 image8

animate1

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.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top