Check alle échte Black Friday-deals Ook zo moe van nepaanbiedingen? Wij laten alleen échte deals zien

[Delphi] Caption change van dynamisch created Labels

Pagina: 1
Acties:
  • 397 views sinds 30-01-2008
  • Reageer

  • DaFreakda
  • Registratie: September 2000
  • Laatst online: 02-11-2022
Ik heb zoals de titel aangeeft een probleem met het wijzigen van de label.Caption van dynamisch gegenereerde Labels in Delphi.

Ik maak de labels, 4labels per systeem, als volgt aan:
Delphi:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
begin
  j:=StrtoInt(SysteemNummer);
  for i:=1 to 4 do
  begin
    lb := TLabel.create(form1);
    lb.parent := form1;
    lb.left := 672 +(j-1) * 50;  //integer
    lb.top := 32 + (i-1) * 16;;  //integer
    lb.font.size := 8;   //integer
    lb.Color := clWhite;
    lb.visible := true;
    lb.Name := ('LabelSysteem'+SysteemNummer+InttoStr(i));
    lb.caption := '';  //string
  end;
end;


Systeemnummer 'j' begint gewoon op 1, en de naam van het 1e Label wordt dus LabelSysteem11, dan LabelSysteem12....... En bij 2 systemen eindigt het met Labelsysteem24.

Nu wil ik als het programma eenmaal runt de caption van deze labels nonstop aanpassen, maar omdat de labels dynamisch gemaakt worden snap ik niet hoe ik naar ze moet verwijzen verderop.
Ik heb vanalles geprobeerd maar ik kom er niet uit...Als ik ipv 'LabelSysteem'+InttoStr(j)+InttoStr(i)' wat ik eigenlijk wil direct de goede naam probeer om te testen gaat het al fout.

Delphi:
1
form1.LabelSysteem11.Caption:=WisselPercentage+'%';


Het programma wil niet runnen, form1 kent die label nu niet, ondanks dat de ' LabelSysteem11' al wel dynamisch is aangemaakt voordat ik de Caption ervan probeer te wijzigen. Ik kom er niet uit |:(

Goed, ik hoop dat ik het probleem duidelijk heb verwoord en dat iemand me kan helpen met tips :)

  • Depress
  • Registratie: Mei 2005
  • Laatst online: 24-11 21:01
Kijk eens naar event handlers van de labels. Ik heb geen idee hoe het in Delphi gaat, maar daar zit de oplossing in.

Google eens naar:
Eventhandlers Delphi

Edit:
Ik begreep je probleem verkeerd.

[ Voor 11% gewijzigd door Depress op 23-07-2007 16:48 ]


Verwijderd

Gaat niet werken op die manier, als je dynamisch aangemaakte componenten wilt gebruiken, kan je die niet simpel op naam in code gebruiken.
Of alles aflopen, of iets als findcomponent gebruiken.

In jouw geval krijg je iets als:
Delphi:
1
2
3
4
5
6
var
  MyLabel : TLabel;
begin
 MyLabel := TLabel(form1.findcomponent('LabelSysteem11'));
 MyLabel.Caption := 'Nieuwe Caption';
end;

wel nog ff errorhandling en controles toevoegen.

Wat je ook nog zou kunnen doen is in een array (multidimensionaal) of idd objectlists de pointers van die labels bijhouden.
Een en ander ligt aan de aard van je applicatie.

[ Voor 28% gewijzigd door Verwijderd op 23-07-2007 16:52 ]


  • jelmervos
  • Registratie: Oktober 2000
  • Niet online

jelmervos

Simple user

Je kunt ook al je dynamisch gecreeerde labels in een lijst (TObjectList bijvoorbeeld) opslaan en hier laten de juiste label in opzoeken. Komt op hetzelfde neer als wat maui71 post, maar is dan een eigen findcomponent systeem welke alleen werkt voor jou labels.

"The shell stopped unexpectedly and Explorer.exe was restarted."


  • dennisvh
  • Registratie: April 2007
  • Laatst online: 30-11 15:33
Je kunt het beste een array bijhouden met verwijzingen naar je gemaakte labels

  • DaFreakda
  • Registratie: September 2000
  • Laatst online: 02-11-2022
Het is bijna 17uur en ik heb er even genoeg van voor vandaag, mooie ambtenaren werktijden jaja, morgen ga ik proberen adhv bovenstaande aanwijzingen het op te lossen.
Bedankt voor de tips!

  • Reptile209
  • Registratie: Juni 2001
  • Nu online

Reptile209

- gers -

Verwijderd schreef op maandag 23 juli 2007 @ 16:47:
Gaat niet werken op die manier, als je dynamisch aangemaakte componenten wilt gebruiken, kan je die niet simpel op naam in code gebruiken.
Of alles aflopen, of iets als findcomponent gebruiken.
Iets uitgebreider dan maui71 al zegt:

Als je goed oplet, gaat Delphi al bij de syntax-check over de zeik. Hij zal aangeven (wat je al constateerde) dat binnen Form1 geen LabelSysteem11 (of welke waarde dan ook) bestaat. Da's ook logisch: dit object is niet gedeclareerd binnen Form1 tijdens design-time, dus heeft de compiler geen flauw idee waar je het over hebt. Nog logischer: als deze constructie zou werken, heb je helemaal geen dynamische labels nodig. Als je ze direct in de code aanspreekt, weet je blijkbaar precies welk label het is en kan je 'm net zo goed designtime op je form zetten. De hele lol van runtime objecten is dat je code kan bepalen hoeveel en wat voor objecten je gebruikt. Dus weet je min of meer per definitie niet tijdens het coden hoeveel objecten je precies hebt.

En dan dus verder werken met FindComponent, zoals aangegeven, of met een:
Delphi:
1
MyLabels: array[1..MAXSYSTEMEN][1..MAXLABELS]

en daar dan runtime je labels inhangen.

Overigens kan (afaik) bijvoorbeeld PHP wel overweg met "dynamische referenties" zoals jij probeert te gebruiken. Dat zal dan wel liggen aan het interpreter versus compiler concept. Het maakt je code er niet noodzakelijk leesbaarder op ;). nofi voor PHP-ers...

Zo scherp als een voetbal!


  • DaFreakda
  • Registratie: September 2000
  • Laatst online: 02-11-2022
Zo het is gelukt, ik heb zoals jullie zeiden Arrays gebruikt. Zoals bij zoveel dingen waar ik met programmeren tegenaanloop is deze oplossing eigenlijk ook weer erg logisch... Een post op dit forum scheelt mij uren/een dag mn hersens kraken op iets wat stiekem helemaal niet zo moeilijk was :) Echt top deze hulp, bedankt!

Voor de volledigheid hier mijn code, onderstaand wordt 'j' maal doorlopen:
Delphi:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
begin
  //Eerst de label aanmaken die de systeemeffectiviteit weergeeft
  j:=StrtoInt(SysteemNummer);
  lb := TLabel.create(form1);
  lb.parent := form1;
  lb.left := 848;  //integer
  lb.top := 176 + (j-1) * 16;;  //integer
  lb.font.size := 8;   //integer
  lb.Color := clWhite;
  lb.visible := true;
  lb.Name := ('LabelSysteem'+SysteemNummer);
  lb.caption := '';  //string
  LabelArray[j,5]:=lb;

  //Nu de labels aanmaken voor elk systeem waar de pompstandpercentages in komen
  for i:=1 to 4 do
  begin
    lb := TLabel.create(form1);
    lb.parent := form1;
    lb.left := 672 +(j-1) * 50;  //integer
    lb.top := 32 + (i-1) * 16;;  //integer
    lb.font.size := 8;   //integer
    lb.Color := clWhite;
    lb.visible := true;
    lb.Name := ('LabelSysteem'+SysteemNummer+InttoStr(i));
    lb.caption := '';  //string
    LabelArray[j,i]:=lb;
  end;
end;

En het aanroepen, caption wijzigen:
Delphi:
1
2
3
4
5
6
7
8
9
10
11
      lb1:=LabelArray[i,1];    //Zuig%
      lb2:=LabelArray[i,2];    //Blaas%
      lb3:=LabelArray[i,3];    //Wissel%
      lb4:=LabelArray[i,4];    //Standby%
      lb5:=LabelArray[i,5];    //Systeemeffectiviteit

      lb1.Caption:=ZuigPercentage+'%';
      lb2.Caption:=BlaasPercentage+'%';
      lb3.Caption:=WisselPercentage+'%';
      lb4.Caption:=StandbyPercentage +'%';
      lb5.Caption:=Work +'%';

  • Reptile209
  • Registratie: Juni 2001
  • Nu online

Reptile209

- gers -

Top! Je kan het nog wat leesbaarder maken met een with statement, zoals ik hieronder laat zien:
DaFreakda schreef op dinsdag 24 juli 2007 @ 09:59:
Delphi:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
begin
  //Eerst de label aanmaken die de systeemeffectiviteit weergeeft
  j:=StrtoInt(SysteemNummer);
  lb := TLabel.create(form1);
  with lb do
  begin
    parent := form1;
    left := 848;  //integer
    top := 176 + (j-1) * 16;;  //integer
    font.size := 8;   //integer
    Color := clWhite;
    visible := true;
    Name := ('LabelSysteem'+SysteemNummer);
    caption := '';  //string
  end
  LabelArray[j,5]:=lb;
[...]
maar dat is een kwestie van smaak en stijl, beslist geen must. Het voordeel is dat je het ook kunt gebruiken als je langere namen dan 'lb' gebruikt, scheelt een boel typwerk en is makkelijker te copy-pasten voor soortgelijke situaties (omdat je de variabelenaam niet hoeft aan te passen).

Zo scherp als een voetbal!


Verwijderd

Reptile209 schreef op dinsdag 24 juli 2007 @ 19:57:
Top! Je kan het nog wat leesbaarder maken met een with statement, zoals ik hieronder laat zien:
'with' is handig en soms heel nuttig, maar ik probeer 't zoveel mogelijk te vermijden. 't Is nl. ook nog heel lastig te debuggen en kan voor lastig te achterhalen bijeffecten zorgen.
Zet bv. 't volgende eens achter een buttonclick op je mainform:
Delphi:
1
2
3
4
5
6
7
8
procedure TForm1.Button1Click(Sender: TObject);
begin
  with CreateMessageDialog('Sure ?', mtConfirmation, [mbYes, mbNo]) do try
    ShowModal;
  finally
    Release;
  end;
end;
Oeps? M'n applicatie sluit acuut af? Ja, want een message dialog is geen VCL form en kent geen Release method (wel een Free). Maar het onderliggende object (mainform) heeft wel een Release method, en Delphi roept die dan aan. Einde applicatie dus. :)

Ander leuk voorbeeld:
Delphi:
1
2
3
4
5
6
7
8
9
with myAddressObject do begin
  // vul object uit bv. edit controls
  with TADOQuery.Create(...) do try
    // set parameters
    // voer query uit
  finally
    Free;
  end;
end;
Zo te zien niks mis mee, maar als 1 van de velden die je wilt vullen myAddressObject.State is (nogal gebruikelijk bij Amerikaanse adressen), dan zal 'ie nu de State property van de TADOQuery nemen, en die is op dat moment altijd 0 (inactive).

Oftewel: heel erg oppassen met 'with'!

Verwijderd

Ik ben niet meer zo aktief met Delphi, maar volgens mij is een TObjectList precies hiervoor bedoeld. Je hoeft dan zelf geen arrays af te lopen en alle objecten worden automatisch opgeruimd met de TObjectList. Ik zou zeggen: zie de Delphi Help er eens op na, want deze array oplossing is tamelijk ranzig.

Verwijderd

Het enige voordeel van een TObjectList t.o.v. een TList is dat 'ie zelf de objecten opruimt bij een delete, clear of free. Maar omdat hier de labels al een owner (form1) meekrijgen die dat zelf ook prima kan doen is er niet echt een toegevoegde waarde.
Ik ben 't wel met je eens dat die 2-dimensionale array niet echt "van deze tijd" is, maar soms zijn ze veel efficienter dan een TList van TLists (van TLists, etc...). Wanneer de dimensies van de matrix vantevoren bekend zijn, of wanneer de matrix niet zo groot is, is er niks mis met een array benadering.
Pagina: 1