Recent

Author Topic: [SOLVED] Dynamically create TPanel  (Read 6309 times)

tudi_x

  • Hero Member
  • *****
  • Posts: 532
[SOLVED] Dynamically create TPanel
« on: August 02, 2017, 03:30:13 pm »
hi All,
i am trying with no luck to show a run time created TPanel on a form as per the below.
the panel caption does not show up.
please advise what i am missing.

thank you

Code: Pascal  [Select][+][-]
  1. unit main;
  2. {$mode objfpc}{$H+}
  3.  
  4. interface
  5. uses
  6.   Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls, ExtCtrls;
  7.  
  8. type
  9.   TForm1 = class(TForm)
  10.     procedure FormCreate(Sender: TObject);
  11.     procedure FormDestroy(Sender: TObject);
  12.   private
  13.     _P: TPanel;
  14.   end;
  15.  
  16. var
  17.   Form1: TForm1;
  18.  
  19. implementation
  20.  
  21. {$R *.lfm}
  22. procedure TForm1.FormCreate(Sender: TObject);
  23. begin
  24.     _P := TPanel.Create(Form1);
  25.     _P.Left:= 10;
  26.     _P.Top := 10;
  27.     _P.Width := 100;
  28.     _P.Height := 50;
  29.     _P.Caption:= 'xxx';
  30.     _P.Show;
  31. end;
  32.  
  33. procedure TForm1.FormDestroy(Sender: TObject);
  34. begin
  35.     FreeAndNil(_P);
  36. end;
  37. end.
« Last Edit: August 02, 2017, 03:51:18 pm by tudi_x »
Lazarus 2.0.2 64b on Debian LXDE 10

Handoko

  • Hero Member
  • *****
  • Posts: 5153
  • My goal: build my own game engine using Lazarus
Re: Dynamically create TPanel
« Reply #1 on: August 02, 2017, 03:47:42 pm »
You need to set its parent, for example:

Code: Pascal  [Select][+][-]
  1.     _P.Parent := Form1;

Blestan

  • Sr. Member
  • ****
  • Posts: 461
Re: Dynamically create TPanel
« Reply #2 on: August 02, 2017, 03:49:10 pm »
and aslo se t visible to true do not call show() in form create because the form is still not visible
Speak postscript or die!
Translate to pdf and live!

tudi_x

  • Hero Member
  • *****
  • Posts: 532
Re: Dynamically create TPanel
« Reply #3 on: August 02, 2017, 03:51:03 pm »
thank you guys!
it worked
Lazarus 2.0.2 64b on Debian LXDE 10

howardpc

  • Hero Member
  • *****
  • Posts: 4144
Re: [SOLVED] Dynamically create TPanel
« Reply #4 on: August 02, 2017, 04:17:55 pm »
You don't need the FormDestroy method at all, since you create _P via TPanel.Create(Form1);
This sets up automatic freeing of _P, so there is no need to duplicate this manually.

wp

  • Hero Member
  • *****
  • Posts: 11916
Re: [SOLVED] Dynamically create TPanel
« Reply #5 on: August 02, 2017, 05:37:25 pm »
A little but essential detail: The parameter given in parenthesis of the Create method is the "owner" of the created object, i.e. when this object is destroyed it will destroy also all objects for which it is the owner. That's fine. But the problem here is that you write: "TPanel.Create(Form1)". This makes the instance of TForm1, called Form1, to the owner of the panel. It may work in 90% of all cases, but it will fail if you'd decide to rename the instance to "Mainform", or "SuperForm", or whatever because "Form1" does not exist.

The correct way is to use "self" as the owner of the created object. Self always refers to the current instance of the class in which it is mentioned.

In total:

Code: Pascal  [Select][+][-]
  1. procedure TForm1.FormCreate(Sender: TObject);
  2. begin
  3.     _P := TPanel.Create(self);   // <-- use self instead of Form1
  4.     _P.Left:= 10;
  5.     _P.Top := 10;
  6.     _P.Width := 100;
  7.     _P.Height := 50;
  8.     _P.Caption:= 'xxx';
  9.     //_P.Show;  // not needed, Visible = true by default
  10. end;

tudi_x

  • Hero Member
  • *****
  • Posts: 532
Re: [SOLVED] Dynamically create TPanel
« Reply #6 on: August 02, 2017, 06:46:24 pm »
thank you guys!

as a suggestion if i may.
where we have this owner approach could it be that Lazarus for the create autocompletes with 'self' instead of blank?
the user experience would not degrade as anyway the owner is mandatory.
would it make the user more productive?
Lazarus 2.0.2 64b on Debian LXDE 10

Handoko

  • Hero Member
  • *****
  • Posts: 5153
  • My goal: build my own game engine using Lazarus
Re: [SOLVED] Dynamically create TPanel
« Reply #7 on: August 02, 2017, 06:57:16 pm »
You may think, the owner usually is the 'self'. But that is not true, I personally set owner of a visual component to nil or the same as its parent.

wp

  • Hero Member
  • *****
  • Posts: 11916
Re: [SOLVED] Dynamically create TPanel
« Reply #8 on: August 02, 2017, 07:30:45 pm »
would it make the user more productive?
Hey come on: If the time needed to type"self" or "parent" or "nil" increases the productivity of a user by a measurable extent then his absolute productivity must be close to zero.

tudi_x

  • Hero Member
  • *****
  • Posts: 532
Re: [SOLVED] Dynamically create TPanel
« Reply #9 on: August 03, 2017, 09:13:50 am »
@wp
i think the IDE is for everybody. for those skilled and for those that are not.
even the ones that are not to productive should be helped.
an enjoyable experience would just make the user happier.
as you mentioned in those 90% of cases the user would be spared of:

1. remembering that the value is mandatory or even worse see this at compilation
2. remembering what is the best practice here
3. mouse click for selection
4. writing the 'self' value
5. reviewing his actions

@Handoko
by auto populating the field you signalize to the user that it is mandatory. if the user is not in agreement with the autocomplete he can just double click and start writing the value he wants. so the difference is of exactly between a click and a double click when you want to change the auto completed value.


Lazarus 2.0.2 64b on Debian LXDE 10

taazz

  • Hero Member
  • *****
  • Posts: 5368
Re: [SOLVED] Dynamically create TPanel
« Reply #10 on: August 03, 2017, 10:26:46 am »
@wp
i think the IDE is for everybody. for those skilled and for those that are not.
even the ones that are not to productive should be helped.
an enjoyable experience would just make the user happier.
as you mentioned in those 90% of cases the user would be spared of:

1. remembering that the value is mandatory or even worse see this at compilation
2. remembering what is the best practice here
3. mouse click for selection
4. writing the 'self' value
5. reviewing his actions

@Handoko
by auto populating the field you signalize to the user that it is mandatory. if the user is not in agreement with the autocomplete he can just double click and start writing the value he wants. so the difference is of exactly between a click and a double click when you want to change the auto completed value.

1) you do not have to remember the compiler will simple refuse to work and you will have to correct it and no that is not worst that is what compilers are invented for.
2) there is no best practice only valid for the case at hand. For example most forms created and destroy inside a single procedure get no owner.
3) No, no, no. No mouse clicks moves on anything of the sort in the code editor if it can't be done from the keyboard you missed something importand

As for autopopulation of the field the answer should be a no. It is already very annoying with the autocompeltion jumping all over the code if something is not 100% perfect I do not need it to force me in to extra work as well.
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

howardpc

  • Hero Member
  • *****
  • Posts: 4144
Re: [SOLVED] Dynamically create TPanel
« Reply #11 on: August 03, 2017, 11:00:41 am »
@tudi_x
It is pretty easy to add a code template (Tools > Code Templates...) that completes the typing of say ".Cre" in the way you want. You can even make the code template autocomplete with [space], [Enter], or whatever.

tudi_x

  • Hero Member
  • *****
  • Posts: 532
Re: [SOLVED] Dynamically create TPanel
« Reply #12 on: August 03, 2017, 11:14:03 am »
thank you howardpc

i will work with code templates for the time being
Lazarus 2.0.2 64b on Debian LXDE 10

 

TinyPortal © 2005-2018