Wie realisiere ich am besten sich wiederholende "Komponente"?
- Zvoni
- Beiträge: 363
- Registriert: Fr 5. Jul 2024, 08:26
- OS, Lazarus, FPC: Windoof 10 Pro (Laz 2.2.2 FPC 3.2.2)
- CPU-Target: 32Bit
- Wohnort: BW
Re: Wie realisiere ich am besten sich wiederholende "Komponente"?
Oder du „sammelst“ diese komponenten in einer liste, array, was auch immer, die eine eigenschaft der form ist, und schon braucht man keine namen, geschweige denn separate variablen, sondern nur einen index…..
Ein System sie alle zu knechten, ein Code sie alle zu finden,
Eine IDE sie ins Dunkel zu treiben, und an das Framework ewig zu binden,
Im Lande Redmond, wo die Windows drohn.
Eine IDE sie ins Dunkel zu treiben, und an das Framework ewig zu binden,
Im Lande Redmond, wo die Windows drohn.
- photor
- Beiträge: 507
- Registriert: Mo 24. Jan 2011, 21:38
- OS, Lazarus, FPC: Arch Linux: L 3.2 (Gtk2) FPC 3.2.2
- CPU-Target: 64Bit
Re: Wie realisiere ich am besten sich wiederholende "Komponente"?
So dachte ich ja auch. Aber, wenn ich den Namen nicht vergebe, kommt die oben angegebene Fehlermeldung beim Programmstart (die 3 Frames werden im FormCreate Created und auf dem MainForm gesetzt).wp_xyz hat geschrieben: Fr 21. Mär 2025, 20:07 Wofür brauchst du den Namen bei einer zur Laufzeit erzeugten Komponente? Du hast doch den Variablennamen (TopPadResultsFrm, BottomPadresultsFrm), um auf die Komponente zuzugreifen. Das ist viel schneller als die Komponente mit "FindComponent" auf der Basis von "Name" erst zu suchen.
Ich habe es noch nicht verstanden.

Photor
-
- Beiträge: 1058
- Registriert: Sa 12. Sep 2015, 12:10
- OS, Lazarus, FPC: Laz stable (2.2.6, 3.x)
- CPU-Target: Win 32/64, Linux64
- Wohnort: Wien
Re: Wie realisiere ich am besten sich wiederholende "Komponente"?
Wenn ich das richtig verstanden habe, erzeugst du mehrere Frames der gleichen Art und positionierst diese auf einem TForm.
In deinem Beispiel erzeugst du die Frames einzeln quasi "per Hand" und hast damit auch entsprechende Variablennamen zur Verfügung.
Um auf jeweils ein bestimmtes (bereits erzeugtes und eingeklebtes) Frame zugreifen zu können gibt es mehrere Möglichkeiten.
Dann ist der Name des erzeugten Objektes nicht nötig.

Ich habe da nur die Antworten nochmal anders zusammen gefasst, vielleicht ist es dann klarer
In deinem Beispiel erzeugst du die Frames einzeln quasi "per Hand" und hast damit auch entsprechende Variablennamen zur Verfügung.
Um auf jeweils ein bestimmtes (bereits erzeugtes und eingeklebtes) Frame zugreifen zu können gibt es mehrere Möglichkeiten.
Die einfachste ist wenn man den Variablennamen kennt unter dem du das Frame erzeugt hast. Dann kannst du direkt zugreifen mitwp_xyz hat geschrieben: Fr 21. Mär 2025, 20:07 Du hast doch den Variablennamen (TopPadResultsFrm, BottomPadresultsFrm)
Code: Alles auswählen
TopPadResultsFrm.GibMirIrgendwas
Kennst du den Variablennamen nicht, kann man aufgrund des zugewiesenen Namens eines Object das Objekt auch mit FindComponent suchen. Was aber langsamer ist.wp_xyz hat geschrieben: Fr 21. Mär 2025, 20:07 Das ist viel schneller als die Komponente mit "FindComponent" auf der Basis von "Name" erst zu suchen.
Wenn du wiederkehrende Aktionen auf alle erzeugten Frame-Objekte anwenden willst (und die Anzahl der Objekte nicht übersichtlich genug ist) dann hat Zvoni vorgeschlagen diese Objekte in irgend einer dir genehmen Struktur zu sammeln, um sie per Index durchlaufen zu können. Willst du in so einer Struktur auf ein bestimmtes Objekt zugreifen brauchst du entweder Index oder Name oder beidesZvoni hat geschrieben: Sa 22. Mär 2025, 08:10 Oder du „sammelst“ diese komponenten in einer liste, array, was auch immer,

Ich habe da nur die Antworten nochmal anders zusammen gefasst, vielleicht ist es dann klarer
- photor
- Beiträge: 507
- Registriert: Mo 24. Jan 2011, 21:38
- OS, Lazarus, FPC: Arch Linux: L 3.2 (Gtk2) FPC 3.2.2
- CPU-Target: 64Bit
Re: Wie realisiere ich am besten sich wiederholende "Komponente"?
Genau. So dachte ich das. Da nur 3 dezidierte Frames gebraucht werden, kann ich die einfach über die Variablen verwalten.charlytango hat geschrieben: Sa 22. Mär 2025, 10:23 Wenn ich das richtig verstanden habe, erzeugst du mehrere Frames der gleichen Art und positionierst diese auf einem TForm.
...
Die einfachste ist wenn man den Variablennamen kennt unter dem du das Frame erzeugt hast. Dann kannst du direkt zugreifen mitwp_xyz hat geschrieben: Fr 21. Mär 2025, 20:07 Du hast doch den Variablennamen (TopPadResultsFrm, BottomPadresultsFrm)Dann ist der Name des erzeugten Objektes nicht nötig.Code: Alles auswählen
TopPadResultsFrm.GibMirIrgendwas
Ich habe mal ein Projekt extrahiert und hänge das an (ist nicht besonders groß - ich hoffe, das kalpt besser, als die Aktion mit dem Bild).charlytango hat geschrieben: Sa 22. Mär 2025, 10:23Kennst du den Variablennamen nicht, kann man aufgrund des zugewiesenen Namens eines Object das Objekt auch mit FindComponent suchen. Was aber langsamer ist.wp_xyz hat geschrieben: Fr 21. Mär 2025, 20:07 Das ist viel schneller als die Komponente mit "FindComponent" auf der Basis von "Name" erst zu suchen.
Wenn du wiederkehrende Aktionen auf alle erzeugten Frame-Objekte anwenden willst (und die Anzahl der Objekte nicht übersichtlich genug ist) dann hat Zvoni vorgeschlagen diese Objekte in irgend einer dir genehmen Struktur zu sammeln, um sie per Index durchlaufen zu können. Willst du in so einer Struktur auf ein bestimmtes Objekt zugreifen brauchst du entweder Index oder Name oder beidesZvoni hat geschrieben: Sa 22. Mär 2025, 08:10 Oder du „sammelst“ diese komponenten in einer liste, array, was auch immer,
Ich habe da nur die Antworten nochmal anders zusammen gefasst, vielleicht ist es dann klarer
Momentan sind die Zeilen mit TopPadResultsFrm.Name := 'TopPadResults'; auskommentiert. Dann wirft das Programm direkt beim Start einen Fehler ("EComponentError") und mit "break" lande ich direkt in Zeile 3537 in control.inc wo steht:
Code: Alles auswählen
inherited SetName(Value);
Packe ich die Zeilen dazu, funktioniert es (damit könnte man das Ganze natürlich als erledigt betrachten).
Von meinen Standpunkt aus, brauche ich den Namen nicht (ich habe die Variablen, über die ich auch an die Elemente auf dem Frame komme). Aber offensichtlich ist der Name nötig.
Aber vielleichthilft ja das Mini-Projekt, meine Verwirrung ein bisschen aufzuklären.
Ciao,
Photor
- Dateianhänge
-
TestFrames.zip
- (140.98 KiB) 84-mal heruntergeladen
Re: Wie realisiere ich am besten sich wiederholende "Komponente"?
Wie schon gesagt, einfach Frame.Name auf '' setzen, dann geht's:
Das Problem ist vielleicht der Begriff "Name". Wenn du eine Variable x vom Typ Integer deklarierst, dann hat sie den Namen "x", und du kannst damit auf sie zugreifen (X := 1). Genauso mit dem TPadResultsFrame: "var TopPadResultsFrame: TPadResultsFrame" erzeugt eine Variable namens "TopPadResultsFrame", und mit "TopPadResultsFrame := TPadResultFrame.Create(Self)" erzeugst du die zugehörige Instanz der Klasse TPadResultsFrame. Mit dem Variablennamen "TopPadResultsFrame" kannst du dann auf diese Instanz zugreifen.
Ich denke die Verwirrung entsteht, weil TPadResultsFrame auch über eine Eigenschaft "Name" verfügt. Die wird aber in der Regel nur für den Objekt-Inspektor benötigt, damit er die aufs Formular geklickte Instanz wiederfindet und damit auch gleich eine *Variable* mit diesem Namen für dich erzeugen kann.
Erzeugst du die Komponente jedoch zur Laufzeit wie oben in deinem Code, wird die Eigenschaft "Name" nicht mehr benötigt - du findest die im Code erzeugte Instanz jederzeit über ihren Variablennamen, den *DU* ihr gegeben hast. Hat eine Komponente dagegen etwas in der Eigenschaft "Name" stehen, dann wird's schwierig, denn der Name muss eindeutig sein.
Die allermeisten Komponenten, die zur Laufzeit erzeugt werden, haben eine leere Eigenschaft "Name" - prima. TFrame ist aber anders: Hier wird aus irgendwelchen Gründen das Feld "Name" mit einem Standard-Wert belegt, der sich aus dem Namen der Klasse ableitet. Ich denke, das könnte durchaus ein Bug sein, und "man" müsste sich das näher ansehen. Auf jeden Fall erhält jede Instanz derselben Klasse denselben Namen - und das geht natürlich schief.
Natürlich - und das hast du in den auskommentierten Zeilen gemacht - kannst du auch selbst einen eindeutigen String für das Feld "Name" vergeben. Das Problem ist aber nur vertagt: Wenn du später, versteckt unter Tausenden von Code-Zeilen, nochmals einen TPadResultsFrame erzeugst und dem wieder den Namen "TopPadResultsFrame" gibst, hast du dasselbe Problem wieder.
Daher ist die generelle Regel: Setze das Feld "Name" jedes eingefügten Frames auf einen Leerstring, damit gehst du allen künftigen Namensdubletten aus dem Weg.
Code: Alles auswählen
procedure TTestFramesMainForm.FormCreate(Sender: TObject);
begin
TopPadResultsFrm := TPadResultsFrame.Create(self);
TopPadResultsFrm.Name := '';
TopPadResultsFrm.Parent := self;
TopPadResultsFrm.PadResultsGrpBx.Caption:= 'Top Pads';
TopPadResultsFrm.Left := 400;
TopPadResultsFrm.Top := 5;
BottomPadResultsFrm := TPadResultsFrame.Create(self);
BottomPadResultsFrm.Name := '' ;
BottomPadResultsFrm.Parent := self;
BottomPadResultsFrm.PadResultsGrpBx.Caption:= 'Bottom Pads';
BottomPadResultsFrm.Left := 700;
BottomPadResultsFrm.Top := 5;
RadialPadResultsFrm := TPadResultsFrame.Create(self);
RadialPadResultsFrm.Name := '';
RadialPadResultsFrm.Parent := self;
RadialPadResultsFrm.PadResultsGrpBx.Caption:= 'Radial Pads';
RadialPadResultsFrm.Left := 1000;
RadialPadResultsFrm.Top := 5;
end;
Ich denke die Verwirrung entsteht, weil TPadResultsFrame auch über eine Eigenschaft "Name" verfügt. Die wird aber in der Regel nur für den Objekt-Inspektor benötigt, damit er die aufs Formular geklickte Instanz wiederfindet und damit auch gleich eine *Variable* mit diesem Namen für dich erzeugen kann.
Erzeugst du die Komponente jedoch zur Laufzeit wie oben in deinem Code, wird die Eigenschaft "Name" nicht mehr benötigt - du findest die im Code erzeugte Instanz jederzeit über ihren Variablennamen, den *DU* ihr gegeben hast. Hat eine Komponente dagegen etwas in der Eigenschaft "Name" stehen, dann wird's schwierig, denn der Name muss eindeutig sein.
Die allermeisten Komponenten, die zur Laufzeit erzeugt werden, haben eine leere Eigenschaft "Name" - prima. TFrame ist aber anders: Hier wird aus irgendwelchen Gründen das Feld "Name" mit einem Standard-Wert belegt, der sich aus dem Namen der Klasse ableitet. Ich denke, das könnte durchaus ein Bug sein, und "man" müsste sich das näher ansehen. Auf jeden Fall erhält jede Instanz derselben Klasse denselben Namen - und das geht natürlich schief.
Natürlich - und das hast du in den auskommentierten Zeilen gemacht - kannst du auch selbst einen eindeutigen String für das Feld "Name" vergeben. Das Problem ist aber nur vertagt: Wenn du später, versteckt unter Tausenden von Code-Zeilen, nochmals einen TPadResultsFrame erzeugst und dem wieder den Namen "TopPadResultsFrame" gibst, hast du dasselbe Problem wieder.
Daher ist die generelle Regel: Setze das Feld "Name" jedes eingefügten Frames auf einen Leerstring, damit gehst du allen künftigen Namensdubletten aus dem Weg.
- photor
- Beiträge: 507
- Registriert: Mo 24. Jan 2011, 21:38
- OS, Lazarus, FPC: Arch Linux: L 3.2 (Gtk2) FPC 3.2.2
- CPU-Target: 64Bit
Re: Wie realisiere ich am besten sich wiederholende "Komponente"?
Hallo Alle,
so gaaanz klar ist mir das nicht. Aber das wichtigste, es ist zum funktionieren zu bekommen. Damit kann ich jetzt mit den Frames weiter probieren (hab in jedem Fall was gelernt).
Danke für Eure Antworten. Wenn weitere Fragen kommen, traue ich mich bestimmt, hier wieder zu fragen.
Ciao,
Photor
PS: habe mein Programm mittlerweile ohne große Probleme auf Frames umgestellt; ist teilweise noch etwas hölzern aber tut.
so gaaanz klar ist mir das nicht. Aber das wichtigste, es ist zum funktionieren zu bekommen. Damit kann ich jetzt mit den Frames weiter probieren (hab in jedem Fall was gelernt).
Danke für Eure Antworten. Wenn weitere Fragen kommen, traue ich mich bestimmt, hier wieder zu fragen.
Ciao,
Photor
PS: habe mein Programm mittlerweile ohne große Probleme auf Frames umgestellt; ist teilweise noch etwas hölzern aber tut.