Delphi Firemonkey中如何读取TRectangle渐变的只写Color/Color1属性
报错根本原因
Firemonkey的TGradient类中,Color、Color1、Color2本质是只写的兼容型快捷赋值属性,本身不存储任何实际颜色值,也没有实现读取逻辑,直接访问必然触发E2130 Cannot read a write-only property编译错误。
这几个属性是FMX架构迭代的遗留产物:早期FMX的渐变是固定双节点结构时,这几个属性是可读写的;后来FMX升级为支持自定义数量停靠点的灵活渐变结构后,为了不破坏旧代码的赋值兼容,保留了这几个属性的setter逻辑,但为了避免多节点场景下读取值和实际配置冲突,直接移除了对应的getter读取接口。
它们的setter逻辑本身是对内部存储结构的快捷操作:调用时会把传入的颜色值,写入内部停靠点集合的固定位置。
正确读取渐变颜色的方法
FMX中所有渐变的实际配置,包括每个节点的颜色、位置,全部统一保存在TGradient.Stops(类型为TGradientStopCollection)集合中,这是官方设计的通用访问通道。集合内的每个TGradientStop对象,都暴露了完全可读写的核心属性:
Color:当前停靠点对应的实际颜色值Offset:当前停靠点在渐变条上的位置,取值范围为0(渐变起点)~1(渐变终点)
历史上那三个只写属性和Stops集合的固定映射规则为:
Color属性的赋值:修改Stops集合中Offset = 0(渐变最左端)的停靠点颜色Color1属性的赋值:修改Stops集合中Offset = 0.5(渐变中点)的停靠点颜色Color2属性的赋值:修改Stops集合中Offset = 1(渐变最右端)的停靠点颜色
修正后的可编译示例
原代码想读取Color1属性值的场景,不需要触碰那个只写属性,直接遍历Stops集合获取对应位置的停靠点颜色即可,修正后的代码如下:
unit Unit1; interface uses System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants, System.Math, // 引入浮点比较单元,解决精度匹配问题 FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.Objects; type TForm1 = class(TForm) Rectangle: TRectangle; procedure FormCreate(Sender: TObject); private { private declarations } public { Public declarations } end; var Form1: TForm1; implementation {$R *.fmx} procedure TForm1.FormCreate(Sender: TObject); var ColorGradient1: TAlphaColor; GradientStop: TGradientStop; begin ColorGradient1 := TAlphaColors.Null; // 初始化默认空颜色 // 遍历所有渐变停靠点,定位对应原Color1的存储位置(Offset=0.5) for GradientStop in Rectangle.Fill.Gradient.Stops do begin // 浮点数比较增加0.001容差,避免存储精度导致的匹配失败 if SameValue(GradientStop.Offset, 0.5, 0.001) then begin ColorGradient1 := GradientStop.Color; Break; end; end; // 读取到的ColorGradient1可直接用于后续业务逻辑 end; end.
实用注意事项
- 如果业务中使用的是自定义多节点渐变,不需要硬匹配0/0.5/1的固定Offset,直接遍历所有Stops节点的
Color和Offset值,就能拿到完整的渐变配置,这是FMX官方推荐的通用访问方式。 - 开发新功能时不要依赖这几个只写属性做逻辑判断,它们仅用于兼容旧版本的赋值逻辑,没有通用的读取能力。
内容的提问来源于stack exchange,提问作者Silver
相关产品推荐
相关产品推荐

