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

如何在Delphi Athens中使用Skia Canvas创建设计时组件?

解决Delphi Athens中Skia组件设计时AccessViolation问题

核心原因

设计时IDE环境不会自动执行运行时的初始化逻辑,比如ALGlobalUseSkia := True这类Skia全局配置代码,导致组件在设计时渲染时因Skia未完成初始化触发AV错误。

具体实现方案

1. 在组件单元的初始化/终结块处理设计时判断

在自定义组件单元的initialization和finalization块中,判断当前是否处于设计时环境,执行对应的Skia初始化:

unit YourCustomSkiaComponent;

interface

uses
  System.Classes, Vcl.Controls, Skia, Skia.Vcl;

type
  TYourCustomSkiaComponent = class(TGraphicControl)
  protected
    procedure Paint; override;
  end;

implementation

uses
  DesignIntf; // 引入设计时相关单元

procedure TYourCustomSkiaComponent.Paint;
var
  LCanvas: ISkCanvas;
begin
  inherited;
  // Skia Canvas渲染逻辑示例
  LCanvas := TSkPaintBoxHelper.CreateSkCanvas(Canvas, ClientRect);
  try
    LCanvas.DrawRect(TRectF.Create(ClientRect), TSkPaint.Create(ColorToSkColor(clRed)));
  finally
    LCanvas := nil;
  end;
end;

initialization
  // 判断是否处于设计时环境
  if Assigned(Designer) then
  begin
    if not ALGlobalUseSkia then
      ALGlobalUseSkia := True;
    // 确保Skia底层库加载完成
    TSkLibrary.Load;
  end;

finalization
  // 设计时环境下可选择性重置全局设置(按需)
  if Assigned(Designer) then
  begin
    // ALGlobalUseSkia := False;
  end;

end.

2. 在组件构造函数或Loaded事件中补充初始化

如果单元初始化块的时机不合适,可在组件内部的构造函数或Loaded事件中处理:

constructor TYourCustomSkiaComponent.Create(AOwner: TComponent);
begin
  inherited;
  if (csDesigning in ComponentState) then
  begin
    if not ALGlobalUseSkia then
      ALGlobalUseSkia := True;
    TSkLibrary.Load;
  end;
end;

3. IDE兼容性配置

  • 确保Skia相关的设计时包(如Skia.Design)已添加到组件包的requires列表并正确安装到IDE
  • 设计时预览尽量简化渲染逻辑,避免执行复杂业务代码,仅保留占位或基础图形绘制

关键注意事项

  • ALGlobalUseSkia是全局变量,设置后会影响整个IDE环境,终结时可按需重置,避免干扰其他组件
  • TSkLibrary.Load必须在所有Skia相关操作前执行,否则会因底层库未加载触发AV

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 15:45:56