为什么我不能使用 onClick 事件处理程序将形状绘制到 lazarus 中的表单上?
Why can I not use the onClick event handler to draw shapes onto a form in lazarus?
我的事件处理程序如下:
procedure TfrmCanvasMethods.btnShapesClick(Sender: TObject);
begin
Canvas.Rectangle(40, 40, 400, 200);
Canvas.Rectangle(80, 80, 360, 160);
Canvas.Ellipse(150, 50, 290, 190);
Canvas.Ellipse(100, 100, 340, 140);
end;
我正在使用 Mac OS X
您必须阅读有关图形 windowing 系统的基础知识。无论是 Windows、MacOS 还是 UNIX X Window.
几乎普遍不是应用程序决定何时、何地绘制什么。操作系统决定并询问应用程序何时执行此操作。应用程序所能做的就是 使 其 window 的某些部分无效 - 即 通知 OS window 的某些部分不再有效,然后等到 OS 想要重新绘制该部分(如果 invalidated [可能永远不会重新绘制)window 被最小化或被另一个 window) 覆盖,然后 - 并且只有在那时 - 绘制。
那你怎么做呢?
方法 1:精通资源并接近真实的 OS 工作流程。
你把 TPaintbox
放在整个 form
上。
- http://docwiki.embarcadero.com/Libraries/Seattle/en/Vcl.ExtCtrls.TPaintBox
- http://lazarus-ccr.sourceforge.net/docs/lcl/extctrls/tpaintbox.html
您将矩形和圆形作为不可见记录或 类 保存在表单变量中。当这些数字发生变化时(例如:您添加了另一个矩形,或者您增加了一些圆直径),您调用 MyForm.MyPaintBox.Invalidate
通知操作系统该 painboxt 的图像不再有效。当 OS 认为是时候刷新图像时,它会调用 MyForm.MyPaintBox.OnPaint
事件,在那种情况下你会像 MyPaintBox.Canvas.Rectangle(40, 40, 400, 200);
那样调用。注意 - 您将重新绘制颜料盒的 canvas,而不是表格的!
procedure TfrmCanvasMethods.btnShapesClick(Sender: TObject);
begin
MyPaintBox.Invalidate();
end;
procedure TfrmCanvasMethods.MyPaintBoxPaint(Sender: TObject);
var Canvas: TCanvas;
begin
Canvas := MyPaintbox.Canvas;
Canvas.Rectangle(40, 40, 400, 200);
Canvas.Rectangle(80, 80, 360, 160);
Canvas.Ellipse(150, 50, 290, 190);
Canvas.Ellipse(100, 100, 340, 140);
end;
方法二:懒惰和资源膨胀
你把 TImage
放在整个 form
上。
该图像将具有包含您想要的任何图片的隐式位图。更重要的是,它会跟踪您对该图片的绘制并自动调用 Invalidate
并自动处理 OS 的重绘请求。
procedure TfrmCanvasMethods.btnShapesClick(Sender: TObject);
var Canvas: TCanvas;
begin
MyImage.Picture.Bitmap.SetSize( MyImage.ClientWidth, MyImage.ClientHeight );
Canvas := MyImage.Picture.Bitmap.Canvas;
Canvas.Rectangle(40, 40, 400, 200);
Canvas.Rectangle(80, 80, 360, 160);
Canvas.Ellipse(150, 50, 290, 190);
Canvas.Ellipse(100, 100, 340, 140);
end;
然而,代价是您可能会分配多达几兆字节的内存,仅用于在 OS 需要刷新表单图片的相对罕见的情况下保留您的图片。
我的事件处理程序如下:
procedure TfrmCanvasMethods.btnShapesClick(Sender: TObject);
begin
Canvas.Rectangle(40, 40, 400, 200);
Canvas.Rectangle(80, 80, 360, 160);
Canvas.Ellipse(150, 50, 290, 190);
Canvas.Ellipse(100, 100, 340, 140);
end;
我正在使用 Mac OS X
您必须阅读有关图形 windowing 系统的基础知识。无论是 Windows、MacOS 还是 UNIX X Window.
几乎普遍不是应用程序决定何时、何地绘制什么。操作系统决定并询问应用程序何时执行此操作。应用程序所能做的就是 使 其 window 的某些部分无效 - 即 通知 OS window 的某些部分不再有效,然后等到 OS 想要重新绘制该部分(如果 invalidated [可能永远不会重新绘制)window 被最小化或被另一个 window) 覆盖,然后 - 并且只有在那时 - 绘制。
那你怎么做呢?
方法 1:精通资源并接近真实的 OS 工作流程。
你把 TPaintbox
放在整个 form
上。
- http://docwiki.embarcadero.com/Libraries/Seattle/en/Vcl.ExtCtrls.TPaintBox
- http://lazarus-ccr.sourceforge.net/docs/lcl/extctrls/tpaintbox.html
您将矩形和圆形作为不可见记录或 类 保存在表单变量中。当这些数字发生变化时(例如:您添加了另一个矩形,或者您增加了一些圆直径),您调用 MyForm.MyPaintBox.Invalidate
通知操作系统该 painboxt 的图像不再有效。当 OS 认为是时候刷新图像时,它会调用 MyForm.MyPaintBox.OnPaint
事件,在那种情况下你会像 MyPaintBox.Canvas.Rectangle(40, 40, 400, 200);
那样调用。注意 - 您将重新绘制颜料盒的 canvas,而不是表格的!
procedure TfrmCanvasMethods.btnShapesClick(Sender: TObject);
begin
MyPaintBox.Invalidate();
end;
procedure TfrmCanvasMethods.MyPaintBoxPaint(Sender: TObject);
var Canvas: TCanvas;
begin
Canvas := MyPaintbox.Canvas;
Canvas.Rectangle(40, 40, 400, 200);
Canvas.Rectangle(80, 80, 360, 160);
Canvas.Ellipse(150, 50, 290, 190);
Canvas.Ellipse(100, 100, 340, 140);
end;
方法二:懒惰和资源膨胀
你把 TImage
放在整个 form
上。
该图像将具有包含您想要的任何图片的隐式位图。更重要的是,它会跟踪您对该图片的绘制并自动调用 Invalidate
并自动处理 OS 的重绘请求。
procedure TfrmCanvasMethods.btnShapesClick(Sender: TObject);
var Canvas: TCanvas;
begin
MyImage.Picture.Bitmap.SetSize( MyImage.ClientWidth, MyImage.ClientHeight );
Canvas := MyImage.Picture.Bitmap.Canvas;
Canvas.Rectangle(40, 40, 400, 200);
Canvas.Rectangle(80, 80, 360, 160);
Canvas.Ellipse(150, 50, 290, 190);
Canvas.Ellipse(100, 100, 340, 140);
end;
然而,代价是您可能会分配多达几兆字节的内存,仅用于在 OS 需要刷新表单图片的相对罕见的情况下保留您的图片。