gpt4 book ai didi

delphi - (Delphi FMX) 如何使用 Canvas.FillText 显示在椭圆的中间?

转载 作者:行者123 更新时间:2023-12-01 16:26:01 34 4
gpt4 key购买 nike

我想将椭圆中间的数字显示为 Canvas 上绘制的文本。坐标(对于椭圆)将存储在数据库内,文本值将存储在数据库的另一部分中。

到目前为止,我所做的是我一直在使用 FMXExpress (Github) 的演示项目(DrawApp)。我将一些程序从私有(private)更改为公开。这些程序包括 StartDrawing(startP:TPointF)、EndDrawing(startP:TPointF)、DoDraw(),这样我就可以从外部单元/对象使用这些函数。该对象使用这些函数与 MouseUp/MouseDown 配合使用,以及一些属性(包括 fDrawing)来区分绘图是否正在进行以及正在使用什么工具(fdEllipse)。

我的主窗体在 FormCreate 中使用以下代码来初始创建 fdrawbox := TMyPaintBox.Create(Rectangle1);矩形 1 位于图像顶部,它代表显示 body 部位的网格,并且能够在图像顶部绘制圆圈。我发现创建文本或椭圆并不难,但是为了创建多个带有标识符的圆圈来区分圆圈,正如我所提到的,我想要一个数字来显示哪个圆圈是哪个。甚至在将来,我可能想更改颜色以显示要关注哪个圆圈。

demonstration for mypaintbox http://www.abatepain.com/abate/OHlbF.jpg

因此,以下代码 (Delphi FMX) 展示了通过利用 TRectangle 作为其父级来创建绘图应用程序。

with fdrawbox do begin
Parent := Rectangle1;
Visible := True;
ForegroundColor := TAlphaColor($FF000000); //
BackgroundColor := TAlphaColor($00000000); //

FuncDraw := TFunctionDraw.fdEllipse; //fdrawbox.fDrawing := True;
StartDrawing(PointF(100, 100));
EndDrawing(PointF(200, 200));
FuncDraw := TFunctionDraw.fdNone;

OnPaint := PaintBox1Paint;
end;

圆圈是使用最后几行创建的,但为了利用 FillText,我需要使用我创建的 OnPaint 函数,代码如下所示。我相信 DrawApp 在内部处理 OnPaint 函数,但它如何处理它仍然未知。但打印“Hello Text!!”仍然是必需的

procedure TMainForm.PaintBox1Paint(Sender: TObject; Canvas: TCanvas);
begin
with Canvas do begin
BeginScene();
//Clear(cbbg.Color);
Font.Style := [];
Font.Size := 12;
Fill.Color := TAlphaColors.Red;
FillText(TRectF.Create(0, 0, 300, 295), 'Hello Text!!', false, 100, [], TTextAlign.Center, TTextAlign.Center); //TFillTextFlag.RightToLeft
EndScene;
end;
Application.ProcessMessages;
end;

有人可以举一个例子来说明如何处理这个问题(可能在单个函数内),我可以在其中打印多个圆圈并在其后添加关联的文本吗?我相信在前面的示例中,我可以自己完成,但我必须手动输入 PointF(用于圆)和 TRectF 用于文本,并且它们都使用不同的值作为坐标。

最佳答案

正如您所注意到的,TMyPaintBox 类不支持文本渲染,也不支持文本输出中经常使用的属性,如字体或颜色等。但是您可以通过在私有(private)中定义字段来自行添加这些属性部分以及用于获取/设置公共(public)部分中的值的属性。

在下面,我假设添加字段 ftextoutffontsizeffontcolor 以及相应的属性 TextOut 字体大小字体颜色

要以与绘制其他元素类型类似的方式添加渲染文本的功能,请将 fdText 作为新枚举添加到 TFunctionDraw

  TFunctionDraw=(fdNone,fdPen,fdLine,fdRectangle,fdEllipse,fdFillBgr,fdBitmapStamp,fdPolyLine, fdText);

然后在TMyPaintBox.DoDraw中向case ffdraw of添加一个新的case选项,例如:

with vCanvas do
begin
BeginScene();
case ffdraw of
//
// other TFunctionDraw enums
//
TFunctionDraw.fdText: begin
{Canvas.}Font.Size := ffonsize; // new field
{Canvas.}Fill.Color := ffontcolor; // new field
{Canvas.}FillText(r, TextOut, False, 1, [],
TTextAlign.Center, TTextAlign.Center);
end;
end;

编辑:

TFunctionDraw.fdText 中对 Canvas 的引用是多余的。删除注释掉的引用文献。要使用的 Canvas 已在 with 语句中定义(添加到要显示的代码中)。哦,我讨厌那些with!

还值得注意的是,如果您只想显示带有文本的圆圈,而不让用户在 Canvas 上绘制,则可以使用自己制作的组件更简单地实现它。

另外,不要直接调用DoDraw。它由 Paint 调用,每当 fdrawbox 失效时都会触发该函数。因此,当您想要强制更新时,请调用 invalidate

编辑结束

然后您可以像任何其他元素绘制一样实现文本渲染(使用您的代码模板):

with fdrawbox do begin
Parent := Rectangle1;
Visible := True;
ForegroundColor := TAlphaColor($FF000000); //
BackgroundColor := TAlphaColor($00000000); //

FuncDraw := TFunctionDraw.fdEllipse; //fdrawbox.fDrawing := True;
StartDrawing(PointF(100, 100));
EndDrawing(PointF(200, 200));

FuncDraw := TFunctionDraw.fdText;
FontSize := 12; // set new property
FontColor := TAlphaColorRec.Red; // set new property
TextOut := 'Hello text!';
StartDrawing(PointF(100, 100));
EndDrawing(PointF(200, 200));

FuncDraw := TFunctionDraw.fdNone;

invalidate;
// OnPaint := PaintBox1Paint; // no need for this
end;

关于delphi - (Delphi FMX) 如何使用 Canvas.FillText 显示在椭圆的中间?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38360343/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com