执行进程时 Gif 图像的动画不起作用

Posted

技术标签:

【中文标题】执行进程时 Gif 图像的动画不起作用【英文标题】:Animation of a Gif image is not working when execute a process 【发布时间】:2021-02-20 00:00:43 【问题描述】:

我有一个 Delphi 项目,它由两个表单组成,即 MainFormDialogForm。当我点击 Button1 时,DialogForm 应该会出现并保持在顶部,直到某个过程完成(该过程需要几秒钟才能完成)。

DialogForm 包含一个Timage 组件。当我单击 Button1 以显示 DialogForm 时,Gif 图像出现但没有动画。这只发生在进程开始时(没有动画工作的进程)。这是什么原因以及如何保持动画直到关闭 DialogForm

procedure TMainForm.Button1Click(Sender: TObject);
var
  gif: TGIFImage;
begin
  Enabled:=false;
  try
        DialogForm.Show;
        DialogForm.Refresh;

        // The process is:
         ...
        ipcAES1.Encrypt;//where ipcAES is part of the IPWorks Encrypt library
        RichEdit1.Text:=ipcAES1.OutputMessage;
    finally
        Enabled:= true;
        DialogForm.Close;
    end;

end;
//--------------------------------------- 
procedure TDialogForm.FormShow(Sender: TObject);
var
  gif: TGIFImage;
begin
  gif := TGIFImage.Create;
  gif.LoadFromFile('D:\preview.gif');
  gif.Animate := True;
    image1.Parent := Self;
    image1.Left := 0;
    image1.Top := 0;
    image1.width := 800;
    image1.height := 800;
    image1.Picture.Assign(gif);
    gif.Animate := True;
    gif.Free;  
end;

【问题讨论】:

欢迎来到 ***!只是一个想法:也许 TGifImage 依靠 Windows 消息处理来制作动画。如果您的进程不调用消息泵,则动画将停止。尝试在处理过程中尽可能频繁地添加 Application.ProcessMessages 调用。这只是一个测试,因为调用 ProcessMessages 可能存在缺陷。我们先看看它是否有效。 另外,请看这个问题:***.com/questions/9573572/… 进程是否在做与 UI 无关的事情,放入一个单独的线程中,这样当你的进程在后台运行时,UI 可以更新(并对 gif 进行动画处理)(注意,你不能使用/从后台线程与 UI/Form 控件交互)。 我已经修改了代码和问题,请检查。 GIF 动画可能涉及到一个计时器,因此,正如前面的 cmets 中所述,主线程在忙时无法更新它。 【参考方案1】:

正如这个线程中的许多人所说,因为处理是在主线程中完成的,所以在这个过程中UI不会更新。

为确保在进程运行时更新 UI,让单独的线程进行处理:

procedure TForm1.Button1Click(Sender: TObject);
var
  aProcessingThread: TThread;
begin
  // First read all data needed by the process from UI controls (or other non-threadsafe parts)
  <data> := ...;

  // Then create a new (anonymous) thread with the code you need to run your process
  aProcessingThread := TThread.CreateAnonymousThread(
    procedure
    begin
      // create the objects you need to do the processing
      ipcAES1 := Txxx.Create;
      try
        // Set the data
        ipcAES1.<data> := <data>;

        // Execute the proces:
        // ...
        ipcAES1.Encrypt;

      finally
        // When the process is done, use 'Synchronize' to interact with the UI
        // again, so you can add the processed data to the RichtEdit and so on...
        TThread.Synchronize(nil,
          procedure
          begin
            // Now you can interact again with the UI
            RichEdit1.Text := ipcAES1.OutputMessage;
            Enabled:= true;
            DialogForm.Close;
          end);
        ipcAES1.Free;
      end;
    end);

  // The thread is now created, but not started/running, so you can now show
  // the dialog and then start the thread, at which point the ButtonClick event
  // exists, but the progress dialog is shown and the thread is running.
  Enabled := False;
  DialogForm.Show;
  aProcessingThread.Start;
end;

当然,这只是一个关于如何使用(匿名)线程在后台进行一些处理的基本示例。 请注意,您需要在线程内处理异常(try/except)。

关于 TGifImage 加载的一个小技巧:只要在 uses 子句中包含 Vcl.Imaging.GIFImg,就可以调用 Picture.LoadfromFile 来加载 gif。

procedure TForm1.FormShow(Sender: TObject);
begin
  image1.Picture.LoadFromFile('D:\preview.gif');

  image1.Parent := Self;
  image1.Left := 0;
  image1.Top := 0;
  image1.width := Image1.Picture.Width;
  image1.height := Image1.Picture.Height;

  (image1.Picture.Graphic as TGIFImage).Animate := True;
end;

【讨论】:

感谢您的回答。但是,Gif 动画会在关闭 DialogForm 并在 RichEdit 组件中显示结果之前停止几秒钟。任何建议将不胜感激。此外,在您的代码中,“aProcessingThread.Start; end);”应该是“aProcessingThread.Start; end;” 尝试将 AnimateLoop 设置为 glContinuously。顺便说一句,我修改了代码。 还是一样。 Gif 动画在关闭 DialogForm 并在 RichEdit 组件中显示结果之前停止几秒钟。 我想补充一点,我已经更改了这一行“RichEdit1.Text := ipcAES1.OutputMessage;”到“ RichEdit1.Text := 'Any String';”,并且gif动画有效。这可能的原因是什么?是因为字符串的长度吗?因为“ipcAES1.OutputMessage”的输出太长(取决于加密字符串的长度) @marocosc 我不知道 ipcAES1 是如何工作的,但可能是对 Outputmessage 的调用也需要很长时间。所以试着把它放在线程里面喜欢'sOutput := ipcAES1.Outputmessage'并在同步部分设置'RichEdit1.Textt := sOutput'。

以上是关于执行进程时 Gif 图像的动画不起作用的主要内容,如果未能解决你的问题,请参考以下文章

为啥我在 paintComponent 中的 gif 动画不起作用?

SVG图像问题,尝试制作动画但stroke-dasharray不起作用

在 JPanel 上为 .GIF 图像制作动画

为啥我的图像动画代码不起作用?

“reg add”似乎在 .BAT 文件中有时不起作用

自定义后退按钮图像在导航栏上不起作用