动态TRect绘制
Dynamic TRect Draw
我正在尝试简单的事情。但我不能:(
我有一个TImage,名字是overview。
我想绘制一个矩形,它在概览上但独立于概览。所以我在概述的前面添加了一个 TImage 并绘制了一个矩形。矩形有效,但我只能看到 TImage 或概览。我试图给 rectImg 一个透明度,但 rectImg 完全消失了。
with rectImg.Canvas do
begin
Pen.Color:= clRed;
Rectangle(0, 0, rectImg.Width, rectImg.Height);
end;
我在颜料上画画,我想画什么。
该矩形可以独立于 img 调整大小。
谢谢指教。
如果我对您的问题的理解正确,您实际上是想在视觉上给图像加框,而不是在原始图形本身上画框,即 rectImg.Picture
不应该 return 带框的图形。立即想到两种方法:
a) 转储 TImage
并使用 TPaintBox
,手动维护核心图形并通过方法调用而不是组件上的 属性 设置进行任何拉伸或其他操作。
b) 扩展 TImage
以在 TImage
完成其标准绘画后引发 OnPaint
事件。
关于 (b),您可以将其作为插入器 class 或自定义组件来完成。作为中介 class 你可以这样做:
1) 在您的表格 class:
正上方重新声明 TImage
type
TPaintEvent = procedure (Sender: TObject; Canvas: TCanvas) of object;
TImage = class(Vcl.ExtCtrls.TImage) //use class(ExtCtrls.TImage) if pre-XE2
strict private
FOnPaint: TPaintEvent;
protected
procedure Paint; override;
published
property OnPaint: TPaintEvent read FOnPaint write FOnPaint;
end;
TMyForm = class(TForm)
//...
2) 如此实现 Paint
重写(由于 TImage
重新定义了基数 class 的 Canvas
属性,所以有点笨拙):
type
TGraphicControlAccess = class(TGraphicControl);
procedure TImage.Paint;
begin
inherited;
if Assigned(FOnPaint) then
FOnPaint(Self, TGraphicControlAccess(Self).Canvas);
end;
3) 以 class:
的形式声明合适的事件处理程序
procedure rectImgPaint(Sender: TObject; Canvas: TCanvas);
4) 像这样实现处理程序 - 注意您需要将 Brush.Style
设置为 bsClear
以不创建填充矩形:
procedure TMyForm.rectImgPaint(Sender: TObject; Canvas: TCanvas);
begin
Canvas.Brush.Style := bsClear;
Canvas.Pen.Color := clRed;
Canvas.Rectangle(0, 0, rectImg.Width, rectImg.Height);
end;
5) 在表单的 OnCreate
事件中分配事件处理程序:
procedure TMyForm.ImagePaint.FormCreate(Sender: TObject);
begin
rectImg.OnPaint := rectImgPaint;
end;
我将插入器 class 转换为自定义组件作为 reader...
的练习
后记
现在我想到了另外两个想法:
- 奇怪的是,FMX 实际上在这里更好,因为它
TImage
提供了一个 OnPaint
事件作为标准。
- 如果它实际上只是您想要的框架,无代码替代方案是用
TShape
覆盖 TImage
,将形状的 Brush.Style
属性 设置为bsClear
就像我们在编码解决方案中所做的那样。在这种情况下,如果您为图像分配了任何 OnClick
或 OnMouseXXX
处理程序,请将形状的 Enabled
属性 设置为 False
。
我正在尝试简单的事情。但我不能:(
我有一个TImage,名字是overview。 我想绘制一个矩形,它在概览上但独立于概览。所以我在概述的前面添加了一个 TImage 并绘制了一个矩形。矩形有效,但我只能看到 TImage 或概览。我试图给 rectImg 一个透明度,但 rectImg 完全消失了。
with rectImg.Canvas do
begin
Pen.Color:= clRed;
Rectangle(0, 0, rectImg.Width, rectImg.Height);
end;
我在颜料上画画,我想画什么。
该矩形可以独立于 img 调整大小。
谢谢指教。
如果我对您的问题的理解正确,您实际上是想在视觉上给图像加框,而不是在原始图形本身上画框,即 rectImg.Picture
不应该 return 带框的图形。立即想到两种方法:
a) 转储 TImage
并使用 TPaintBox
,手动维护核心图形并通过方法调用而不是组件上的 属性 设置进行任何拉伸或其他操作。
b) 扩展 TImage
以在 TImage
完成其标准绘画后引发 OnPaint
事件。
关于 (b),您可以将其作为插入器 class 或自定义组件来完成。作为中介 class 你可以这样做:
1) 在您的表格 class:
正上方重新声明TImage
type
TPaintEvent = procedure (Sender: TObject; Canvas: TCanvas) of object;
TImage = class(Vcl.ExtCtrls.TImage) //use class(ExtCtrls.TImage) if pre-XE2
strict private
FOnPaint: TPaintEvent;
protected
procedure Paint; override;
published
property OnPaint: TPaintEvent read FOnPaint write FOnPaint;
end;
TMyForm = class(TForm)
//...
2) 如此实现 Paint
重写(由于 TImage
重新定义了基数 class 的 Canvas
属性,所以有点笨拙):
type
TGraphicControlAccess = class(TGraphicControl);
procedure TImage.Paint;
begin
inherited;
if Assigned(FOnPaint) then
FOnPaint(Self, TGraphicControlAccess(Self).Canvas);
end;
3) 以 class:
的形式声明合适的事件处理程序procedure rectImgPaint(Sender: TObject; Canvas: TCanvas);
4) 像这样实现处理程序 - 注意您需要将 Brush.Style
设置为 bsClear
以不创建填充矩形:
procedure TMyForm.rectImgPaint(Sender: TObject; Canvas: TCanvas);
begin
Canvas.Brush.Style := bsClear;
Canvas.Pen.Color := clRed;
Canvas.Rectangle(0, 0, rectImg.Width, rectImg.Height);
end;
5) 在表单的 OnCreate
事件中分配事件处理程序:
procedure TMyForm.ImagePaint.FormCreate(Sender: TObject);
begin
rectImg.OnPaint := rectImgPaint;
end;
我将插入器 class 转换为自定义组件作为 reader...
的练习后记
现在我想到了另外两个想法:
- 奇怪的是,FMX 实际上在这里更好,因为它
TImage
提供了一个OnPaint
事件作为标准。 - 如果它实际上只是您想要的框架,无代码替代方案是用
TShape
覆盖TImage
,将形状的Brush.Style
属性 设置为bsClear
就像我们在编码解决方案中所做的那样。在这种情况下,如果您为图像分配了任何OnClick
或OnMouseXXX
处理程序,请将形状的Enabled
属性 设置为False
。