【问题标题】:Loading images into TImage, via array通过数组将图像加载到 TImage 中
【发布时间】:2011-09-30 15:32:48
【问题描述】:

我对 delphi 很陌生,正在为我的 A 级做一个项目。当我运行我的代码时,图像只是不显示,我到处找,我的老师帮不了我。谁能告诉我我错过了什么?

    const
       Animal : array[0..6] of string =                    ('Bears','Dogs','Cats','Chickens','Horses','Cows','Monkeys');
    ImagePaths : array [0..6] of string
      = ('img0.JPG', 'img1.JPG', 'img2.JPG', 'img3.JPG', 'img4.JPG', 'img5.JPG',
        'img6.JPG');

  var i:integer;
  Images : array [0..11] of TImage;

procedure LoadImages;
  var
  k,l:integer;
  begin
  Randomize;
  k:=Random(11);
  for l:= 0 to k do
  begin
    Images[l] := TImage.Create(nil);
    Images[l].Picture.LoadFromFile(ImagePaths[i])
  end

结束;

procedure TForm4.FormCreate(Sender: TObject);
begin
randomize;
i:=random(6);
QuestionLbl.Caption:=Format('How many %s are there?',[Animal[i]]);
LoadImages;
end;

这个想法是,如果有帮助的话,会显示相同随机选择的动物的随机数量的图像,然后让孩子进行计数和输入。非常感谢任何帮助。

编辑。

因为这只是一个原型,所以我已将其全部复制到一个新应用程序中,这是我没有包含的所有代码:

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics,     Controls, Forms,
  Dialogs, StdCtrls,jpeg, ExtCtrls;

type
  TForm1 = class(TForm)
    QuestionLbl: TLabel;
    procedure FormCreate(Sender: TObject);
      private
    { Private declarations }
  public
    { Public declarations }
  end;

同样的错误正在发生,恐怕我太无知了,无法遵循我确信非常明确的指示。

【问题讨论】:

    标签: arrays delphi delphi-7 timage


    【解决方案1】:

    似乎缺少的是您需要告诉图像哪个控件是其父控件,以便它可以显示在屏幕上。这样做:

    Images[l].Parent := TheForm;
    

    显然你的表单变量会有一个不同的名字,但我相信你知道它叫什么。

    当你这样做时,你会发现它们最终都重叠在一起。然后分配给TopLeft 属性以定位。最后,您可能希望设置图像的HeightWidth 属性以匹配图像的尺寸Images[l].Picture.HeightImages[l].Picture.Width


    我无法想象您的代码为什么会产生访问冲突,但这可能与您提出的问题无关。下面的代码证明我上面说的是正确的:

    procedure TMyForm.FormCreate(Sender: TObject);
    var
      Image: TImage;
    begin
      Image := TImage.Create(Self);
      Image.Parent := Self;
      Image.Picture.LoadFromFile('C:\desktop\image.jpg');
      Image.Top := 0;
      Image.Left := 0;
      Image.Height := Image.Picture.Height;
      Image.Width := Image.Picture.Width;
    end;
    

    没有你的完整代码,我无法调试你的 AV。

    【讨论】:

    • 添加后引发异常。它显示“地址 00465679 的访问冲突”,你知道这是为什么吗?感谢您之前的回复。
    • @danny 很难说。您没有在问题中包含足够的代码。您应该安排 LoadImages 接收表单作为参数,然后您可以将其用作父级。将Self 传递给LoadImages
    • 我上面写的是正确的。我看不到你的代码。我无法解释 AV。在调试器下运行,看看哪里出错了。
    • 抱歉之前的评论过早发了,我在原帖上加了一些,够了吗?非常感谢所有的帮助。
    • 在调试器下运行,在 'Images[l].Parent := Form1;' 处中断
    【解决方案2】:

    为什么你不把你的 TImages 放在表单上,​​而只是 LoadFromFile 你想显示的那些? 出现在我看来会更容易。

    但是:你想要完成什么?从代码中,我可以想象您正在尝试向人们展示一些图像并计算它们并回答问题......

    因此,如果您在表单中添加(并定位)11 个空(无图像)TImage,您可以这样做:

    // Any trouble in copying your FormCreate header, David? ;-)
    procedure TMyForm.FormCreate(Sender: TObject);
    begin
      Images[0] := Image_N1; // First TImage
      Images[1] := Image_N2;
      Images[2] := Image_N3;
      // Do that until the 12 slots are filled
      // As a exercise for Danny Robinson( the OP ), you can do that in a for..do using 
      // the Form.Components array property to automate it instead of 
      // doing one-at-a-line
    end;
    
    procedure ClearImages;
    var I: Integer;
    begin
      for I = Low(Images) to High(Images) do
      begin
        Images.Picture.Graphic := Nil;
      end;
    end;
    
    
    
    procedure LoadImages;
    var
      k,l:integer;
    begin
      ClearImages;
      Randomize;
      k:=Random(11);
      for l:= 0 to k do
      begin
        Images[l].Picture.LoadFromFile(ImagePaths[i])
      end;
    
    end;
    

    如果您仍需要动态创建 TImage,只需创建 12 个 TImage 一次在 FormCreate 上(如大卫的回答)并继续调用 LoadImages。

    编辑:

    一些想法,因为你正在学习。
    即时创建可视化控件是一项非常无聊(当然,在我看来)的任务,其中涉及:

    • 显然是在创建对象
    • 将其分配给父控件(表单不需要此传递)
    • 根据您的视觉规划调整大小
    • 将其放置在您想要的父控件的位置
    • 设置它的锚点,以便在调整父控件大小时重新定位和/或调整大小(如果需要)
    • 只有在这一切之后,让它做你想做的事情(在这种情况下,显示图像)。

    几乎所有这些步骤David Heffernan's answer 都显示了它的代码。但是,除非你真的需要动态布局,否则在设计时做所有这些更实用;-)

    【讨论】:

    • 您绝对正确,这就是我最初计划对其进行编码的方式,但尝试了我发布的测试内容。当我去学校吃午饭时,有人保存并记录了我。谢谢,我试试看。
    • 我不知何故有一种错觉,即拥有 TImage 的数组 [0..11] 会自动将表单上的所有 TImage 放入数组中。希望我能找到其他人来责备。我目前无法访问我的计算机,但我想这应该可以。非常感谢大家的帮助。
    【解决方案3】:

    您需要设置每个TImageParent 属性才能在屏幕上看到它们。但是,您不能使用全局 Form 指针变量,因为在触发 OnCreate 事件时它还没有被分配。所以将表单的Self 指针作为LoadImages() 的参数传入。

    您还有另一个错误 - 您声明了一个 12 元素的 TImage 数组,但为图像路径声明了一个 7 元素的字符串数组。你使用Random()的方式,如果它生成一个大于6的值,你将超出String数组的范围。

    试试这个:

    const
      ...
      ImagePaths : array [0..6] of string = ('img0.JPG', 'img1.JPG', 'img2.JPG', 'img3.JPG', 'img4.JPG', 'img5.JPG', 'img6.JPG');
    
    var
      i: integer;
      Images : array [0..6] of TImage;
    
    procedure LoadImages(AParent: TWinControl);
    var
      i, k: integer;
    begin
      Randomize;
      k := Random(7);
      for i := 0 to k do
      begin
        Images[i] := TImage.Create(nil);
        Images[I].Parent := AParent;
        // set other properties, like Left/Top...
        Images[l].Picture.LoadFromFile(ImagePaths[i]);
      end;
    end;
    
    procedure TForm4.FormCreate(Sender: TObject);
    begin
      ...
      LoadImages(Self);
    end;
    

    【讨论】:

    • +1。不过,如果您将k := Random(7) 更改为k := Random(High(Images) + 1),那将是一个更好的答案。不必要的硬编码限制,尤其是在给新来者的帖子中,简直令人讨厌;他们树立了一个坏榜样。 :)
    • 我认为如果 Application.CreateForm 被调用,表单变量通常会很早就分配。它是在调用 NewInstance 之后,如果有内存的话,在调用构造函数之前分配的。
    【解决方案4】:

    TImage 组件必须在屏幕上绘制, 为此,将 1pixel 面板作为父级来加载图形。 就像在加载屏幕中一样,因此图像可以用作默认的 TImage 程序。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多