德尔福颤动者

发布于 2024-11-04 08:53:23 字数 260 浏览 4 评论 0原文

显示应用程序正在执行某些操作的最佳解决方案是什么?

我尝试显示进度指示器,但没有成功。

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

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

我想显示一个throbber,就像网络浏览器使用的那样,只要有东西正在更新它一直在转动。

光标也可以处于 crHourGlass 模式。

What is the best solution to show that the application is doing something?

I tried showing a progress indicator, but it did not work.

UPDATE: -------------

A progress bar works fine, but isn't what I want.

I want to show a throbber, like what Web browsers use, so as long as something is being updated it keeps turning.

Cursor can also be in crHourGlass mode.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

倾`听者〃 2024-11-11 08:53:23

试试这个:

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.

Unit1

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.

图像

图片1
image2
image3
image4
image5
image6
image7
image8

animate1

Try this:

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.

Unit1

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.

The Images

image1
image2
image3
image4
image5
image6
image7
image8

animate1

り繁华旳梦境 2024-11-11 08:53:23

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

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

You are probably running your time consuming task in the main thread.

One option is to move it to a background thread which will allow your message queue to be serviced. You need it to be serviced in order for your progress bar, and indeed any UI, to work.

美男兮 2024-11-11 08:53:23

更新问题的答案:

  • 生成动画 gif,例如 此处
  • 将 GIF 库添加到您的环境中 (JEDI JVCL+JCL )
  • 插入一个 TImage 并加载生成的 gif,
  • 使其在需要时可见

Answer to the updated question:

  • generate an animated gif e.g. here
  • add a GIF library to your environment (JEDI JVCL+JCL)
  • insert a TImage and load the generated gif
  • make it visible if you need it
下雨或天晴 2024-11-11 08:53:23

一个指标就OK了。更改后您必须调用 Application.ProcessMessages

A indicator is OK. You have to call Application.ProcessMessages after changing it.

套路撩心 2024-11-11 08:53:23

“显示该应用程序正在执行某些操作的最佳解决方案是什么?” - 将鼠标光标设置为 crHourGlass?或者创建另一个表单/框架/等来提醒用户应用程序正在“做”某事,并且他需要等待。

"What is the best solution to show that that application is doing something?" - set mouse cursor to crHourGlass? or to create another form/frame/etc which attentions the user that the application is 'doing' something, and he needs to wait.

薄情伤 2024-11-11 08:53:23

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

不要使用 Application.ProcessMessages 因为这会引入可能的重入问题。

From your lengthy task, you can occasionally update a visual indicator, like a progress bar or anything else. However, you need to redraw the changes immediately by calling Update on the control that provides the feedback.

Don't use Application.ProcessMessages as this will introduce possible reentrancy issues.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文