Für alles, was in den übrigen Lazarusthemen keinen Platz, aber mit Lazarus zutun hat.
fliegermichl
Lazarusforum e. V.
Beiträge: 1647 Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Lazarus Fixes FPC Stable
CPU-Target: 32/64Bit
Wohnort: Echzell
Beitrag
von fliegermichl » Do 21. Nov 2019, 10:38
Hallo zusammen,
ich versuche hier gerade dynamisch einige Radiobuttons mit Labels zu generieren. Wenn man im Objektinspektor die Caption eines Labels bearbeitet, dann passt sich die Eigenschaft Height automatisch an. Das scheint bei einer Zuweisung per Programm nicht der Fall zu sein. Kleines Beispiel:
Code: Alles auswählen
const
lines : array[1..3] of string = (
'Ich bin nur eine einfache Zeile',
'Ich bin dann aber schon' + LineEnding +
'zwei Zeilen groß',
'Und ich einer der''s gleich übertreiben' + LineEnding +
'muß und ganze drei' + LineEnding +
'Zeilen in Beschlag nehmen muß');
procedure TForm1.FormCreate(Sender: TObject);
var rb : TRadiobutton;
lb : TLabel;
i : integer;
y : integer;
begin
y := 5;
for i := 1 to 3 do
begin
rb := TRadioButton.Create(Application);
rb.Parent := self;
rb.Left := 10;
rb.Top := y;
rb.Caption := Format('Auswahlmöglichkeit %d', [i]);
y += rb.Height + 3;
lb := TLabel.Create(Application);
lb.Parent := self;
lb.top := y;
lb.Left := 20;
lb.WordWrap := True;
lb.AutoSize := True;
lb.Caption := Lines[i];
y += lb.Height + 5;
end;
end;
Das schaut dann aber so aus:
Dynamisch generierte Labels dynlabels.PNG (7.81 KiB) 3377 mal betrachtet
Wie kann ich nun die tatsächlich vom Label in Beschlag genommene Höhe ermitteln?
Zuletzt geändert von
fliegermichl am Fr 22. Nov 2019, 09:10, insgesamt 1-mal geändert.
fliegermichl
Lazarusforum e. V.
Beiträge: 1647 Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Lazarus Fixes FPC Stable
CPU-Target: 32/64Bit
Wohnort: Echzell
Beitrag
von fliegermichl » Do 21. Nov 2019, 10:55
Ich hab das ganze jetzt nochmal mit einer aktuellen Lazarusversion 2.0.7 fixes probiert. Gleiches Ergebnis.
m.fuchs
Lazarusforum e. V.
Beiträge: 2817 Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:
Beitrag
von m.fuchs » Do 21. Nov 2019, 11:09
Wie wäre es denn, wenn du die mit Lazarus mitgelieferten Layoutmechanismen verwendest?
Code: Alles auswählen
procedure TForm1.FormCreate(Sender: TObject);
var
rb : TRadiobutton;
lb : TLabel;
i : integer;
begin
Self.ChildSizing.Layout := cclLeftToRightThenTopToBottom;
Self.ChildSizing.ControlsPerLine := 1;
Self.ChildSizing.EnlargeHorizontal := crsHomogenousChildResize;
for i := 1 to 3 do begin
rb := TRadioButton.Create(Application);
rb.Parent := self;
rb.BorderSpacing.Left := 10;
rb.BorderSpacing.Top := 5;
rb.Caption := Format('Auswahlmöglichkeit %d', [i]);
lb := TLabel.Create(Application);
lb.Parent := Self;
lb.BorderSpacing.Top := 3;
lb.BorderSpacing.Left := 20;
lb.WordWrap := True;
lb.AutoSize := True;
lb.Caption := Lines[i];
end;
end;
Und vernünftige Variablennamen wären auch eine gute Idee.
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de
fliegermichl
Lazarusforum e. V.
Beiträge: 1647 Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Lazarus Fixes FPC Stable
CPU-Target: 32/64Bit
Wohnort: Echzell
Beitrag
von fliegermichl » Do 21. Nov 2019, 11:18
Danke für die Info.
Von Childsizing und Borderspacing hab ich noch nie was gehört. Woran kann es liegen, daß die Angabe lb.Borderspacing.Left := 20 keine Auswirkung hat?
m.fuchs
Lazarusforum e. V.
Beiträge: 2817 Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:
Beitrag
von m.fuchs » Do 21. Nov 2019, 13:47
fliegermichl hat geschrieben: Von Childsizing und Borderspacing hab ich noch nie was gehört.
Dann empfiehlt sich ein Blick hierhin:
Wiki: Autosize/Layout
fliegermichl hat geschrieben: Woran kann es liegen, daß die Angabe lb.Borderspacing.Left := 20 keine Auswirkung hat?
Doch hat es, leider nimmt es dann alle Elemente auf den gleichen Abstand mit.
Kann sein, dass du dieses Problem nur mit
Anchors lösen kannst.
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de
wp_xyz
Beiträge: 5156 Registriert: Fr 8. Apr 2011, 09:01
Beitrag
von wp_xyz » Do 21. Nov 2019, 13:51
Ja, ich würde auch mit Anchors arbeiten.
Ansonsten funktioniert dein Code richtig, wenn du ihn später aufrufst, z.b. in FormShow.
m.fuchs
Lazarusforum e. V.
Beiträge: 2817 Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:
Beitrag
von m.fuchs » Do 21. Nov 2019, 14:09
Hier noch die Variante mit Anchors:
Code: Alles auswählen
procedure TForm1.FormCreate(Sender: TObject);
var
CurrentRadioButton : TRadiobutton;
CurrentLabel : TLabel;
CurrentControl: TControl = nil;
i : integer;
begin
for i := 1 to 3 do begin
CurrentRadioButton := TRadiobutton.Create(Self);
CurrentRadioButton.Parent := Self;
CurrentRadioButton.AnchorParallel(akLeft, 10, Self );
if Assigned(CurrentControl) then
CurrentRadioButton.AnchorToNeighbour(akTop, 3, CurrentControl)
else
CurrentRadioButton.AnchorParallel(akTop, 3, Self);
CurrentRadioButton.Caption := Format('Auswahlmöglichkeit %d', [i]);
CurrentControl := CurrentRadioButton;
CurrentLabel := TLabel.Create(Self);
CurrentLabel.Parent := Self;
CurrentLabel.AnchorParallel(akLeft, 20, Self );
CurrentLabel.AnchorToNeighbour(akTop, 3, CurrentControl);
CurrentLabel.WordWrap := True;
CurrentLabel.AutoSize := True;
CurrentLabel.Caption := Lines[i];
CurrentControl := CurrentLabel;
end;
end;
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de
fliegermichl
Lazarusforum e. V.
Beiträge: 1647 Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Lazarus Fixes FPC Stable
CPU-Target: 32/64Bit
Wohnort: Echzell
Beitrag
von fliegermichl » Do 21. Nov 2019, 14:48
Tatsache,
wenn ich das nicht im OnCreate mache, funktioniert es wie erwartet.
Danke für Eure Hilfe!
m.fuchs
Lazarusforum e. V.
Beiträge: 2817 Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:
Beitrag
von m.fuchs » Do 21. Nov 2019, 15:06
Du solltest trotzdem die fertigen Layouthelfer verwenden. Sonst wirst du irgendwann Probleme bekommen, wenn irgendeine Auflösung/Schriftgröße/sonstewas deine Oberfläche zerhackt.
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de
Warf
Beiträge: 2122 Registriert: Di 23. Sep 2014, 17:46
OS, Lazarus, FPC: Win10 | Linux
CPU-Target: x86_64
Beitrag
von Warf » Do 21. Nov 2019, 19:31
Um deine eigentliche Frage zu beantworten, sowas sollte es für dich tun:
Code: Alles auswählen
function LabelHeight(const Label: TLabel): Integer;
begin
with TCanvas.Create(nil) do
try
Font := Label.Font;
Result := TextHeight(Label.Caption);
finally
Free;
end;
end;
Wobei Label.Height eigentlich auch gehen müsste, eventuell musst du vorher mal das label updaten lassen via:
fliegermichl
Lazarusforum e. V.
Beiträge: 1647 Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Lazarus Fixes FPC Stable
CPU-Target: 32/64Bit
Wohnort: Echzell
Beitrag
von fliegermichl » Do 21. Nov 2019, 23:03
Warf hat geschrieben:
Wobei Label.Height eigentlich auch gehen müsste, eventuell musst du vorher mal das label updaten lassen via:
Wie gesagt, es funktioniert, aber nicht im OnCreate Event des Formulars
af0815
Lazarusforum e. V.
Beiträge: 6786 Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:
Beitrag
von af0815 » Fr 22. Nov 2019, 07:06
Layouten mache ich niemals im OnCreate.
Für mich passiert das alles beim ersten OnActivate, dort mache ich ein Init meines Programmes, da zu diesen Zeitpunkt alles aus der LCL/FCL stabil ist. Auch das erzeugen der Frames mit meinem Layout ist hier Erfahrungsgemäß sicher. Zusätzlich erzeugt mein Hauptformular (=Main) alle weiteren Formulare bei Bedarf und Initialisiert diese auch. Damit bin ich nie von der Reihenfolge der Erstellung der Formulare in der *.lpr Datei abhängig.
Ach ja vielleicht ein weiterer Tip zu Layout in Frames, da ich die sehr stark dynamisch verwende. In einem Frame lege ich immer ein (flaches) Panel in den Hintergrund und baue auf diesen Panel mein Layout auf (Auch mit OnResize des Panel wenn nötig). Niemals Anchors auf die Seiten des Frame beziehen. Der Grund liegt darinnen, wie die LCL später die Frames in das Zielform bringt. Es gibt manchmal Seiteneffekte beim Layouten zwischen Komponenten auf/in Frames mit den Komponeten die diese Frames beinhalten, bzw. wenn Frames gegenseitig mit Anchors abhängig gemacht werden in komplexen Layouts.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in
LazInfos/LazSnippets ).
fliegermichl
Lazarusforum e. V.
Beiträge: 1647 Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Lazarus Fixes FPC Stable
CPU-Target: 32/64Bit
Wohnort: Echzell
Beitrag
von fliegermichl » Fr 22. Nov 2019, 09:10
Ich werde wohl nicht drum herum kommen, mich einmal näher mit den Möglichkeiten der Layouterei in Lazarus zu befassen. Mein eigentliches Problemchen ist aber gelöst.