Skia4Dephi 的 Demo 程序界面架构分析

Skia4Delphi 在 Delphi 里面利用 Skia 画图 简介 Skia 是一个 2D 库,画图性能非常好。是由 Google 开源出来的。 在 Delphi 里面如何使用这个 2D 库,来利用它提供的一些好处? 有一个开源的项目,Skia4Delphi 很好地解决了这个问题。它使得 Delphi 的 VCL 程序和 FMX 程序都能利用 Skia 库来画 2D 图。比如,可以用 Delphi 的程序来显示 WebP 这种格式的图,SVG 的图,等等。当然,Skia 还有很多 2D 图的算法。 这个开源项目在:https://github.com/skia 阅读详情

前言

Skia 是一个高效率的 2D 画图引擎,由 Google 开源出来。目前可以运行在 Android, iOS 和 Win32 上面。

Skia4Delphi 是一个开源的 Delphi 控件,它封装了对 Skia 的调用,让 Delphi 的代码可以很简单地使用 Skia 来代替 Delphi 原本使用的系统库(比如 Windows 的 GDI)。尤其是在安卓下,Delphi 自己的支持 FireMonkey 的图形库效果不是太好,使用 Skia 代替,基本上不需要修改程序就能获得更好的效果。比如 TArc 在安卓上圆弧不平滑的问题直接解决。

界面框架

Skia4Delphi 带来的 Demo 程序,不管是在 Windows 桌面还是在手机上,运行效果都类似一个标准的手机 APP:多层菜单,一层一层点菜单进入,一层一层点回退按钮退出。

Sika4Delphi 的 Demo 程序包括 2 个,一个是 For VCL 的,一个是 For FMX 的。For VCL 的当然只能在 Windows 平台上运行,而 For FMX 的,当然可以编译发布到 Delphi FireMonkey 支持的多个不同的操作系统平台上,包括 Windows, MacOS, Android, iOS 。

界面框架解析

仔细查看它的 Demo 程序的代码,发现 VCL 的程序和 FMX 的程序,界面框架的实现方式基本相同,就是把界面的主要元素做成一个基本的 Form,其它 Form 都从这个 Form 继承。

这种类似手机 APP 的界面,基本元素包括:顶部一个工具栏,工具栏的左侧是回退按钮(一个向左打尖头符号)。还包括一个底部工具栏,用于显示一些提示信息。中间则是主要的显示区域。

不管界面是第几层,都采用这个框架。每一层,可能有进入下一层的按钮,点击后显示下一层。每一层的回退按钮,点击后本层消失,显示上一层的界面。

抽象出共性后,Skia4Delphi 的 Demo 程序,将这些共性,实现为一个基本的 Form,这里它取名叫做:【TfrmBase】,如下:

TfrmBase = class(TForm)

这个 Form 有一个最底层的托盘控件,在 VCL 的 Demo 里面它是一个 TPanel,在 FMX 的 Demo 里面,它是一个 TLayout.。所有的界面控件都摆放在这个托盘上。基于 Delphi 的代码框架,所谓的摆放,就是:某个界面元素比如 Label1.Parent := 托盘控件。

在此基础上,这个 TftmBase 还实现了几个类方法以及用于存放创建的 Form 实例的类变量。

显示一个新的界面

在设计期,每个新的界面(比如不同的菜单栏,或者显示不同内容的 Form),都是一个 Form,这些 Form 都继承自 TfrmBase。因此它们都包含了一个顶部的工具栏以及工具栏左侧的回退按钮。这个工具栏和回退按钮,又都摆放在最底层的托盘控件上,以它的 VCL Demo 程序为例,摆放在名字叫做 pnlContent 的一个 TPanel 上面。

不管在哪个 Form 里面点击菜单按钮需要显示一个新的 Form,都是调用 TfrmBase 的方法。因此,不管在哪个 Form 里面需要显示下一层的 Form,都无需额外写代码。随便挑一个按钮菜单的代码看看:

procedure TfrmControls.pnlTSkSVGClick(Sender: TObject);
begin
  ChildForm<TfrmTSkSVG>.Show;
end;

上述代码中, ChildForm 是一个函数:

function TfrmBase.ChildForm<T>: T;
var
  LSelfIndex: Integer;
begin
  Assert(T.InheritsFrom(TfrmBase));
  LSelfIndex := FCreatedFormsList.IndexOf(Self);
  if (LSelfIndex >= 0) and (LSelfIndex < FCreatedFormsList.Count - 1) and (FCreatedFormsList[LSelfIndex + 1].ClassType = T) then
    Exit(T(FCreatedFormsList[LSelfIndex + 1]));
  Result := CreateForm<T>;
  TfrmBase(Result).pnlContent.Align := TAlign.alClient;
  TfrmBase(Result).pnlBack.Visible := FShowingFormsList.Count > 0;
  FCreatedFormsList.Add(TfrmBase(Result));
end;

这个函数把需要显示的下一层的界面(一个 Form)创建好,并放到类变量 FCreatedFormsList 里面去方便管理。因此,不管在哪一层的界面里面创建了下一层的界面,它的 Form 实例的一个指针,都在 FCreatedFormsList 这个变量里面。

泛型

上述代码中比较有意思的是,这个被所有真正用于显示的 Form 继承的父类基础 Form,它是没办法知道子类的。按照传统的 Delphi 的语法,这里根本没法这样写。但这里它利用了新的泛型语法,这里直接使用了尖括号加 T,也就是泛型,返回也是 T。因此,真正调用时填入子类 Form 的类名,在父类里面,可以创建子类!

上述代码中的 Show 方法的代码则是:

procedure TfrmBase.Show;
begin
  DoShow;
end;

//这个 DoShow 的代码:
procedure TfrmBase.DoShow;
begin
  pnlTip.Visible := not lblTipDescription.Caption.IsEmpty;
  if Self = Application.MainForm then
  begin
    pnlBack.Visible := False;
    FShowingFormsList.Add(Self);
  end
  else
  begin
    if FShowingFormsList.Count > 0 then
      FShowingFormsList.Last.pnlContent.Visible := False;
    FShowingFormsList.Add(Self);
    pnlContent.Parent := Application.MainForm; // 关键一行代码在这里
  end;
  inherited;
  pnlContentResize(nil);
end;

上述代码,真正显示下一级 Form 界面的代码就是这一行:

pnlContent.Parent := Application.MainForm;

把这个被创建的下一级 Form 里面作为底层托盘的 Panel 的 Parent 设置为主Form,因此这个 Panel 被摆到主 Form 上面了。

显示界面的方法

所以,这里显示的下一层 Form 的界面,并不是下一层 Form 直接 Show 出来,而是把它内部的 Panel 摆放到主 Form 上显示出来。因此,这里的每一层的 Form 在设计期存在,仅仅是用来作为一个界面模块的容器!在运行期创建它的实例以后,并没有显示它,而是把它当内容(作为托盘的 Panel)直接拿出来显示到主 Form 上面。

回退按钮呢?

那么,显示出来的界面,点了左上角的回退按钮,它做了什么操作?看代码:

procedure TfrmBase.pnlBackClick(Sender: TObject);
begin
  {$IF CompilerVersion >= 32}
  TThread.ForceQueue(nil,
    procedure
    begin
      CloseForm(Self);  //调用 CloseForm 方法,传入的参数是当前这个 Form 的实例指针。
    end);
  {$ELSE}
  TThread.CreateAnonymousThread(
    procedure
    begin
      TThread.Queue(nil,
        procedure
        begin
          CloseForm(Self);
        end);
    end).Start;
  {$ENDIF}
end;


//真正的关闭 Form 的代码在这里,这是一个类方法

class procedure TfrmBase.CloseForm(const AForm: TfrmBase);
var
  LFormIndex: Integer;
  LAction: TCloseAction;
  I: Integer;
begin
  LFormIndex := FShowingFormsList.IndexOf(AForm);
  if LFormIndex < 0 then
    Exit;
  LAction := TCloseAction.caFree;
  AForm.DoClose(LAction);
  if LAction = TCloseAction.caNone then
    Exit;
  if LFormIndex = 0 then
    Application.Terminate
  else
  begin
    LFormIndex := FCreatedFormsList.IndexOf(AForm);
    Assert(LFormIndex > -1);
    for I := FCreatedFormsList.Count - 1 downto LFormIndex do
    begin
      FCreatedFormsList[I].Free;
      FShowingFormsList.Remove(FCreatedFormsList[I]);
      FCreatedFormsList.Delete(I);
    end;
    FShowingFormsList.Last.pnlContent.Visible := True;
  end;
end;

在上面的类方法 CloseForm 里面,它根据这个 Form 的实例指针,在之前保存指针的类变量 FCreatedFormsList 里面,把指针从 List 里面删除掉,并且把这个 Form 对象释放掉。

Form 对象被释放掉,它内部被用于显示界面元素的托盘 Panel 也就被释放掉了,被它遮住的底下的界面就显示出来了。

到这里,我们发现,多层界面,其实就是多层 Panel 的层层堆叠。上面一层被释放掉,下面一层就显示出来了。

但这些多个 Panel,并不是在设计期,都挤在一个 Form 里面进行设计,而是分别在不同的 Form 里面设计,这样可以做到界面的模块化,便于代码管理。

题外话:我也见过非常复杂很多层显示界面的程序,所有界面控件都放在一个 Form 里面设计,运行期用代码决定显示哪个控件以及每个控件的显示位置。这样做,界面上控件太多,拥挤在一起,设计期非常难找到想要的控件,不是一种好的开发模式。

总结

虽然 Skia4Delphi 的 Demo 程序中,运行在 Windows 上的 VCL 程序以及可以运行在手机上的 FMX 程序,都采用了相同的类似手机 APP 的层叠界面的设计模式,但最实用的还是手机 APP,因为屏幕太小,不可能一屏里面还划分几个区域,只能是一层一层的界面叠加。因此,这样的设计模式,在做手机 APP 的时候非常值得学习。实际上它的 FMX 的 Demo 程序的框架,可以直接用于我们自己开发的手机 APP。

之前我自己开发的手机 APP 虽然也是多层界面叠加,但管理界面堆叠层次的代码就显得比较罗嗦,没有这个 Skia4Delphi 的 Demo 程序这样设计良好的框架,并且将所有界面的显示和回退的代码都集中到一个基类里面,在其它界面里面无需重复。

又及:

这个 Skia4Delphi 的 Demo 程序,每个界面模块是在 Form 里面实现的。要加载一个新的界面就要创建一个 Form 实例。而 Form 占用的资源较多。这里可以采用 Frame 来作为界面设计的基础框架。我自己写代码测试了一下,上述构思,基于 Frame 来做,也是可以实现的。

告别锯齿和卡顿:手把手教你用 Delphi 12 的 Skia4Delphi 控件打造炫酷 UI(含 TSkLabel/TSkSVG 详解) 本文详细介绍了如何利用 Delphi 12 的 Skia4Delphi 控件打造流畅、无锯齿的炫酷 UI。通过 TSkLabel 和 TSkSVG 等组件的实战示例,展示了其在文本渲染和矢量图形处理中的卓越性能,帮助开发者提升应用视觉体验。 阅读详情

相关推荐

Delphi 12 实战:用Skia4Delphi轻松搞定Lottie动画和WebP图片(附完整Demo)

本文详细介绍了如何在Delphi 12中使用Skia4Delphi高效处理Lottie动画和WebP图片。从基础配置到高级应用,包括动画控制、性能优化、WebP图片加载与保存等实战技巧,帮助开发者快速实现专业级视觉效果。文章还提供了完整Demo项目,便于读者快速上手和实践。

weixin_30411819的博客 326

Skia4Delphi 3.2.0 from March 04, 2022

Cross-platform 2D graphics API based on Google's Skia Graphics Library. It provides a comprehensive 2D API that can be used across mobile, server and desktop models to render images.

Delphi 12 Athens 实战:手把手教你用Skia引擎提升FireMonkey App的UI流畅度

本文详细介绍了如何在Delphi 12 Athens中使用Skia引擎显著提升FireMonkey应用的UI流畅度。通过对比传统渲染引擎与Skia的性能差异,提供三步激活Skia的配置方法,并分享优化资源加载、平台调优及避开性能陷阱的实战技巧,帮助开发者彻底革新应用性能。

weixin_29012765的博客 405

Delphi 12.3控件之Skia4Delphi-6.4.0-beta1-Setup.exe

Delphi 12.3控件之Skia4Delphi_6.4.0-beta1_Setup.exe

Delphi第三方控件推荐与源码解析:从选型到实战

在桌面开发领域,组件化开发是提升效率的关键。从VCL基础组件到第三方控件库,合理选型能大幅降低复杂业务场景的编码成本。以TeeChart图表控件为例,其在新版Delphi中的集成与渲染优化常成为开发者关注焦点;同时,多线程编程中TTask与TThread的选择、字符串字典键的性能优化等基础问题,也直接影响工具类软件的稳定性。从实际工程视角出发,梳理表格、图表、图像处理等方向的优秀第三方控件,并分享源码阅读方法、安装部署技巧与常见故障排查经验,帮助开发者避开授权、兼容性等深坑,真正发挥组件化开发的价值。

weixin_33660045的博客 89

TMS FMX UI Pack 3.7.3.0:Delphi D10.4跨平台UI工程级解决方案

FMX(FireMonkey)是Embarcadero提供的跨平台UI框架,其核心挑战在于平台渲染差异、高DPI适配与样式一致性。TMS FMX UI Pack作为深度集成FMX原生架构的组件套件,通过强类型控件继承、三层主题覆盖机制和原生桥接模块(如TMSFMXNativeList),系统性解决Android滚动卡顿、iOS状态栏异常、macOS文本模糊等典型工程痛点。它不依赖WebView或外部渲染层,所有组件直驱FMX消息循环,兼顾设计时兼容性与运行时平台特化能力。特别适配Delphi 10.4(Sy

weixin_33507732的博客 275

【Delphi】最新版12中新功能:Skia4Delphi

介绍最新版Delphi 12中的 Skia功能

sensor_WU 博客 4861

Delphi 10.3 集成 PDFium 实现高性能 PDF 渲染与编辑

PDF 渲染与编辑是桌面应用中高频但高门槛的技术需求,其核心依赖底层 PDF 引擎(如 PDFium)的稳定封装与内存模型适配。原理上需解决跨语言绑定、Unicode 字符支持、多线程解码、高 DPI 像素对齐及表单数据持久化等关键问题。技术价值在于摆脱外部 DLL 依赖、实现进程内全控式 PDF 处理,并支持断点调试与深度定制。典型应用场景包括电子签章系统、教务文档自动化、医疗报告生成等对格式精度与国产化可控性要求严苛的领域。本文聚焦 Delphi 10.3 下基于 PDFium 的源码级集成实践,覆盖中

weixin_33552698的博客 259

google中的skia的安装和使用(skia4delphi)

网站:Skia4Delphi 1、下载。 https://github.com/skia4delphi/skia4delphi/releases/download/v3.4.0/Skia4Delphi_3.4.0_Setup.exe 2、安装。 选择11版本,自动编译,安装。 3、运行。demo 路径:D:\Skia4Delphi\Samples\Demo\VCL\Projects\RAD Studio 11 Alexandria ...

Winfredzhang的博客 1188

Delphi XE7安卓开发实战:FMX原生编译与JNI调优指南

Object Pascal 是一种面向对象的通用编程语言,常用于快速应用开发(RAD);FMX(FireMonkey)是 Embarcadero 提供的跨平台 UI 框架,支持 Windows、macOS、iOS 和 Android。其核心原理在于通过 AOT 编译生成原生 ARM 代码,并借助 JNI Bridge 调用 Android SDK 接口,而非 WebView 套壳或 Java 反射层。这种架构赋予了 Delphi 应用接近原生的性能和低内存开销,特别适合已有 VCL/FMX 桌面项目向安卓轻

weixin_30072453的博客 309

Delphi7集成Chromium渲染引擎实战指南

Chromium渲染引擎是现代Web应用的核心执行环境,基于Blink排版引擎、V8 JavaScript引擎和Skia图形库,提供完整的HTML5/CSS3/JS执行能力。其技术价值在于脱离系统IE依赖,实现跨版本操作系统兼容与高性能GPU加速渲染。典型应用场景包括工业控制界面升级、医疗设备Web化交互、政企遗留系统前端现代化改造等。对于Delphi7这类经典原生开发环境,通过CEF4Delphi可将Chromium 119+内核以DLL方式静态嵌入,无需重写业务逻辑即可获得2024年标准的Web运行时能

weixin_30512965的博客 260

Miniblink49 保姆级教程:2 行代码内嵌 Chromium 内核浏览器控件,一步到位

Miniblink49 是一个基于 Chromium 49 引擎的轻量浏览器内核,它用单文件和几行代码,就能在你的 Windows 桌面程序里嵌入一个真实的网页渲染控件。项目对自己的定位很直接:一个小巧、轻量的浏览器内核,用来取代 wke 和 libcef。如果你的目标是给桌面应用加 Web 界面、跑无界面爬虫,或者做一个小体积的 Electron,它都值得放进候选清单。 ## 为什么不用整套

gitblog_00690的博客 693

Delphi 12原生Excel引擎:FlexCel纯Pascal实现.xlsx读写与报表开发

Excel文件格式(.xlsx)是基于OpenXML标准的ZIP压缩包结构,其核心原理在于将工作簿、工作表、样式、公式等以XML文档组织并打包。采用纯Pascal实现的本地引擎,可绕过COM依赖与Office进程,显著提升跨平台兼容性与部署鲁棒性,技术价值体现在零外部依赖、可调试源码、支持VCL/FMX双平台及国密算法扩展。典型应用场景包括老旧Delphi报表系统迁移、Android/iOS移动端数据导出、金融级加密报表生成等。本文聚焦Delphi 12(Athens)环境下TMS FlexCel v7.8

weixin_26934905的博客 212

用skia实现2D绘制

skia是谷歌的一个开源2D引擎,用来实现利用CPU实现2D图形绘制。 下面是老朽写的一个例程,实现功能如下: 1.窗口的创建 2.图片解码 3.在窗口的任意位置绘制指定大小和透明度的图片 4.绘制文字 因为对OpenGL熟悉,所以不怎么喜欢用SDL,而是采用OpenGL创建绘制窗口。先由glfw创建窗口,然后skia负责渲染,最后opengl只负责将skia传过来的pixel画出来。 main函...

czhzasui的博客 9421

TRichView 21.6 + ScaleRichView 8:Delphi/C++Builder 工业级富文本排版方案

富文本渲染是桌面应用开发中的基础能力,涉及文本布局、图像嵌入、表格处理、高DPI适配与跨平台打印等核心问题。其底层原理依赖于可定制的文档对象模型(DOM)与独立于系统GDI的渲染管线,技术价值在于保障所见即所得精度、缩放不失真及源码级可调试性。典型应用场景包括仪器控制台操作手册、电子工单系统、医疗设备配置工具等对UI稳定性要求严苛的工业软件。TRichView 21.6 提供纯Pascal实现的TRVData内容引擎,ScaleRichView 8 则专精高DPI视图适配,二者组合构成当前 Delphi/C

weixin_27791839的博客 266

delphi d11 + skia4delphi 绘制的仪表盘,已经封装成简单的控件

版本说明: delphi d11.2 skia4delphi 4.0.1 type TJsonDashboard = class(TObject) private FView: TSKPaintBox; FMinValue: Integer; FMaxValue: Integer; FCurValue: Integer; procedure SetMinValue(const Value: Integer); procedure SetMaxValue(const Value: Integer); procedure SetCurValue(const Value: Integer); protected property MinValue: Integer read FMinValue write SetMinValue; property MaxValue: Integer read FMaxValue write SetMaxValue; property CurValue: Inte

skia4delphi:为Delphi带来强大的2D图形能力

在软件开发中,图形渲染能力的强大与否直接影响着应用的视觉效果和用户体验。skia4delphi 是一个开源的跨平台2D图形库,为Delphi开发者提供了一套功能丰富、性能卓越的图形渲染解决方案。 ## 项目介绍 skia4delphi 是基于 Google 开源的 Skia 图形库的 Delphi 封装。Skia 本身是一个专注于精确、高质量和高效性能的2D图形渲染库,被广泛应用于 Googl

gitblog_00937的博客 1037

delphi仪表盘,基于d11.3和skia4delphi以及fmxui扩展的类似于汽车仪表盘,可以灵活的设置各种参数

delphi仪表盘,基于d11.3和skia4delphi以及fmxui扩展的类似于汽车仪表盘,可以灵活的设置各种参数

上一篇: Delphi 的操作符重载 - Record 结构体
下一篇: Delphi FireMonkey TMemo 修改背景颜色和边框颜色
pcplayer
博客等级 码龄26年 633粉丝 284原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值