问题
I'm very new to delphi, doing a project for my A level. When I run my code the images just don't show, I've looked everywhere and my teacher can't help me. Can anyone tell me what I'm missing?
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
end;
procedure TForm4.FormCreate(Sender: TObject);
begin
randomize;
i:=random(6);
QuestionLbl.Caption:=Format('How many %s are there?',[Animal[i]]);
LoadImages;
end;
The idea is that a random number of images of the same randomly selected animal is displayed for a child to then count and input, if that helps. Much appreciate any help.
edit.
as this is only a prototype I have copied it all to a new application and this is all the code I didn't include:
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;
The same error is occurring and I'm afraid I'm too ignorant to follow what I'm sure were very clear instructions.
回答1:
Why you just don't put your TImages on the form, and just LoadFromFile the ones you want to show ? Appear to me that would be easier.
But: what you trying to accomplish? From the code, I can imagine you were trying to show a number of images to people count them and answer the question...
So, if you add (and position) the 11 empty(no image) TImages in the form, you can do:
// 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;
If you still need to create the TImages on the fly, just create the 12 TImages once on FormCreate (as in David's answer) and keep calling the LoadImages.
EDIT:
Some ideas, since you are learning.
Creating visual controls on-the-fly is a very boring(in my opinion, of course) task that involves:
- Creating the object, obviously
- Assigning it to a parent control (forms doesn't need this pass)
- Sizing it accordingly to your visual planning
- Positioning it in the place of the parent control you want it to be
- Set it's anchors, for it to reposition and/or resize when the parent control is resized (if needed)
- Only after all this, make it do what you want it to do (in this case, showing images).
Almost all those steps David Heffernan's answer show the code for it. But, unless you really need a dynamic layout, doing all those on design-time is more practical ;-)
回答2:
What appears to be missing is that you need to tell the image which control is its parent so that it can appear on screen. Do that like this:
Images[l].Parent := TheForm;
Obviously your form variable will have a different name, but I'm sure you know what it's called.
When you do this you will find that they all end up on top of each other. Assign to the Top
and Left
properties to position then. Finally you will likely want to set the Height
and Width
properties of the images to match the dimensions of the images, Images[l].Picture.Height
and Images[l].Picture.Width
.
I can't imagine why your code produces an access violation but it's presumably unrelated to the question you asked. The following code proves that what I say above is correct:
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;
Without your full code I cannot debug your AV.
回答3:
You need to set the Parent
property of each TImage
in order to see them onscreen. You can't use the global Form pointer variable, though, because it has not been assigned yet when the OnCreate
event is triggered. So pass in the form's Self
pointer as a parameter of LoadImages()
instead.
You have another bug - you declared a 12-element TImage
array but declared a 7-element String array for the image paths. The way you are using Random()
, if it generates a value above 6, you will go out of bounds of the String
array.
Try this instead:
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;
回答4:
TImage component must to be painted on the screen, for do so make a 1pixel panel as the parent to load the graphics. like in a loading screen so the images can be used as default TImage procedures.
来源:https://stackoverflow.com/questions/7612740/loading-images-into-timage-via-array