2

我正在为我的学校项目在 Lazarus 写 2-3 Trees 应用程序。

一切都完成了,现在开始玩 GUI(我得到的好 GUI 的分数与我得到的好等的分数相同。插入功能,这很奇怪,但 nvm)。

当我在树中有 10 多个节点时,我的 300*200 图像大小就不够大了。

我想在 TForm 上有一个像 300*200 的 TImage 组件,但实际上它会像 10000 * 10000 并且您可以在其中滚动。

甚至可能吗?

谢谢

编辑使问题更清楚

  1. 2-3 树是一种数据结构。在纸上绘制以查看其工作原理时,它看起来像这样http://www.cosc.canterbury.ac.nz/research/RG/alg/tree23.gif

  2. 作为 lazarus/delphi 中的真正菜鸟(必须在 lazarus 中进行)使用此代码来绘制它(即使我怀疑你需要它来回答我的问题):

    procedure TStrom.Paint(Image: TImage);
    

    变量 C:TCanvas;

    程序 Paint1(V:TNode;宽度,X,Y:整数);开始

    if V.L <> nil then    //left child
    begin
      C.MoveTo(X, Y);
      C.LineTo(X - Width div 3, Y + 50);
      Paint1(V.L, Width div 3, X - Width div 3, Y + 50);
    end;
    
    if V.S <> nil then    //middle child 
    begin
      C.MoveTo(X, Y);
      C.LineTo(X + Width div 3, Y + 50);
      Paint1(V.S, Width div 3, X + Width div 3, Y + 50);
    end;
    
    if V.P <> nil then     //right child
    begin
      C.MoveTo(X, Y);
      C.LineTo(X + Width div 3 + Width div 3, Y + 50);
      Paint1(V.P, Width div 3, X + Width div 3 + Sirka div 3, Y + 50);
    end;
    
    if V.isLeaf then
    begin
      C.Ellipse(X - 15, Y - 15, X + 15, Y + 15);
      C.TextOut(X - 3, Y - 8, IntToStr(V.Info1));
    end
    else
    begin
      C.Rectangle(X - 15, Y - 15, X + 15, Y + 15);
      C.TextOut(X - 7, Y - 8, IntToStr(V.Info1));
      C.Rectangle(X + 15, Y - 15, X + 50, Y + 15);
      if V.Info2 <> 0 then
        C.TextOut(X + 27, Y - 8, IntToStr(V.Info2));
    end;
    
  3. draw 函数效果很好,但是一些(大部分)高度为 3+ 的节点被绘制在其他节点上,所以看起来很糟糕。该节点位于另一个节点上,并且在它旁边不是 20 像素。

  4. 我想我会让树被画得很大的图像,但它会在一个小“面板”中。像这样:TImage 实际上是 1000*1000,但在表格中你只能看到它的一小部分。在这部分中会有水平和垂直滚动条,因此您可以滚动图像并查看部分中绘制的内容。(就像当您滚动浏览网络浏览器以查看页面底部时 :) )

  5. 我们不允许使用任何其他代码,只是内置在 lazarus 组件中。(我们也不允许创建新组件 -> 不知道为什么)

  6. 虽然我仍然对如何做到这一点感到好奇,但我的应用程序不再需要它(安装了第二台监视器以查看它是否有帮助,但它不会,所以我想我会深入研究我的绘画方法少量 :-) )

4

2 回答 2

3

您的编辑更清楚地表明您想要绘制一个原理图,就像您链接到的示例中的最后一棵树一样。

从您的代码中,我了解到您正在将所有节点、子节点和叶子绘制到单个画布上,从而生成一个大图像/位图。现在,如何只显示大图像的一部分,旁边有滚动条?

显而易见的选择是将 aTPaintBox放在 a 上TScrollBox。我不知道 Lazarus 中的默认组件套件,但我希望它们都存在。给画框一个与你的视觉树的边界相等的大小,你就设置好了:滚动条将自动显示。

油漆盒有一个OnPaint活动,您可以在其中通过绘画来完成绘画工作PaintBox.Canvas。为了优化这一点,您可以将绘图限制为PaintBox.Canvas.ClipRect(在滚动框中可见的油漆框部分),但我怀疑这很困难,因为您已经难以计算相邻节点之间的正确距离。(关于那个:我希望总树的最大宽度和高度是总深度的函数,但我很容易弄错。)

如果 Lazarus 没有 a TPaintBox,则使用 aTImage其中也有一个Canvas属性。缺点是TImage将所有绘图操作“存储”在一个大的内部位图中,当您的树扩展过多时,这可能会引发内存或资源问题。

于 2013-01-16T18:04:05.660 回答
1

可以将所有图像组合成一张大图像吗?如果是这样,那么也许这个组件回答了你的问题。

它是 的后代TGraphicControl,能够进行动画缩放。通过拖动选择矩形放大图形的一部分,通过双击缩小整个图形。如果您需要帮助更新它以便能够执行平移操作,请拍摄。

于 2013-01-16T07:33:49.260 回答