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

Delphi FMX中PaintBox绘制图形显示在Form而非控件内的问题

FMX PaintBox绘制坐标偏移问题解决

问题原因

VCL中PaintBox的画布坐标默认是控件自身的客户区坐标,而FMX的PaintBox Canvas使用Form全局坐标系统,直接用(0,0)绘制会对应Form的左上角,而非PaintBox的内部左上角。

解决方法

需要将PaintBox的局部坐标转换为全局坐标,以下是两种常用实现方式:

方式1:利用控件Position偏移坐标

直接通过PaintBox的Position属性获取它在Form中的位置,偏移绘制矩形:

procedure TForm1.Button1Click(Sender: TObject);
var
  MyRect: TRectF;
begin
  MyRect := TRectF.Create(0, 0, 300, 300);
  // 偏移到PaintBox的左上角位置
  MyRect.Offset(PaintBox1.Position.X, PaintBox1.Position.Y);
  
  PaintBox1.Canvas.BeginScene;
  try
    PaintBox1.Canvas.DrawRect(MyRect, 1);
    PaintBox1.Canvas.FillRect(MyRect, 1);
  finally
    PaintBox1.Canvas.EndScene;
  end;
end;

方式2:使用LocalToAbsolute方法转换坐标

通过FMX提供的坐标转换方法,将局部坐标转为全局坐标,更适配复杂布局(比如存在父容器嵌套的情况):

procedure TForm1.Button1Click(Sender: TObject);
var
  MyRect: TRectF;
  AbsoluteOrigin: TPointF;
begin
  MyRect := TRectF.Create(0, 0, 300, 300);
  // 获取PaintBox局部原点对应的全局坐标
  AbsoluteOrigin := PaintBox1.LocalToAbsolute(TPointF.Create(0, 0));
  MyRect.Offset(AbsoluteOrigin.X, AbsoluteOrigin.Y);
  
  PaintBox1.Canvas.BeginScene;
  try
    PaintBox1.Canvas.DrawRect(MyRect, 1);
    PaintBox1.Canvas.FillRect(MyRect, 1);
  finally
    PaintBox1.Canvas.EndScene;
  end;
end;

额外提示

如果要绘制适配PaintBox大小的内容,可以直接使用PaintBox1.LocalRect获取控件自身的客户区矩形,无需手动计算偏移:

MyRect := PaintBox1.LocalRect;
// 对MyRect进行调整后再绘制

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 07:57:07