You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Delphi 11 FMX中TCanvas绘制如何保留原有图案避免Repaint清除

Delphi 11 FMX 保留TRectangle画布绘制内容的解决方案

FMX的OnPaint事件机制和Lazarus不同,每次调用Repaint时会先清空画布再执行绘制代码,要保留已有内容,得自己维护一个绘制缓冲区。以下是具体实现步骤:

  • 添加缓冲区成员变量:在Form的类声明中添加一个TBitmap作为绘制缓冲区:

    private
      FBufferBitmap: TBitmap;
    
  • 初始化和释放缓冲区:在Form创建时初始化Bitmap,销毁时释放资源:

    procedure TForm2.FormCreate(Sender: TObject);
    begin
      FBufferBitmap := TBitmap.Create;
      FBufferBitmap.SetSize(Rectangle1.Width, Rectangle1.Height);
    end;
    
    procedure TForm2.FormDestroy(Sender: TObject);
    begin
      FBufferBitmap.Free;
    end;
    
  • 修改按钮点击逻辑:直接在缓冲区画布上绘制新内容,再触发重绘:

    procedure TForm2.Button1Click(Sender: TObject);
    var
      rect: TRectF;
      x: Integer;
    begin
      x := Random(100);
      rect := TRectF.Create(100 - x, 100 - x, 100 + x, 100 + x);
    
      FBufferBitmap.Canvas.BeginScene;
      try
        FBufferBitmap.Canvas.Stroke.Color := TAlphaColors.Black;
        FBufferBitmap.Canvas.DrawEllipse(rect, 255);
      finally
        FBufferBitmap.Canvas.EndScene;
      end;
    
      Rectangle1.Repaint;
    end;
    
  • 重写OnPaint事件:把缓冲区的内容绘制到TRectangle的画布上:

    procedure TForm2.Rectangle1Paint(Sender: TObject; Canvas: TCanvas; const ARect: TRectF);
    begin
      Canvas.DrawBitmap(FBufferBitmap, ARect, ARect, 1);
    end;
    
  • 处理尺寸变化(可选):如果TRectangle的大小可能改变,在OnResize事件里调整缓冲区尺寸:

    procedure TForm2.Rectangle1Resize(Sender: TObject);
    begin
      if Assigned(FBufferBitmap) then
        FBufferBitmap.SetSize(Rectangle1.Width, Rectangle1.Height);
    end;
    

这样每次点击按钮,新的椭圆会叠加在缓冲区中,Repaint时直接绘制整个缓冲区内容,就能保留之前的所有图案了。

内容的提问来源于stack exchange,提问作者JJJ

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 00:28:22