Genaue Ausrichtung von Komponenten

Rund um die LCL und andere Komponenten
Antworten
Benutzeravatar
theo
Beiträge: 9573
Registriert: Mo 11. Sep 2006, 19:01

Genaue Ausrichtung von Komponenten

Beitrag von theo »

Hallo

Ich stolpere gerade über eine Merkwürdigkeit, die mich zuvor gar nicht gestört hat.
Es gelingt mir nicht, im Code einen TButton neben einem TEdit so zu platzieren, dass die beiden optisch die gleiche Höhe und den gleichen Abstand von Oben haben (Top).

Beispiel: Diese beiden Elemente haben die gleiche "Height" von 25. Optisch sehen sie aber nicht gleich hoch aus.

GTK2 im Designer:
editbutton_gtk2.png
editbutton_gtk2.png (69.2 KiB) 292 mal betrachtet

Schlimmer noch, auf Qt5 sieht der gleiche Code wieder anders aus:

Qt5 Runtime:
editbutton_qt5.png
editbutton_qt5.png (37.67 KiB) 292 mal betrachtet

Gibt es da Erkenntnisse dazu?
Gibt es eine Art "Outer Height"? Muss man mit den Theme Services arbeiten, wenn man das "schön" haben möchte?
Wer weiss mehr?

Benutzeravatar
Ally
Beiträge: 221
Registriert: Do 11. Jun 2009, 09:25
OS, Lazarus, FPC: Win und Lazarus Stable release
CPU-Target: x64

Re: Genaue Ausrichtung von Komponenten

Beitrag von Ally »

Hallo Theo,

Mit dem Ankereditor und etwas transpiration, bekommt man das ganz gut platformunabhängig hin.

Anker.png
Anker.png (33.16 KiB) 273 mal betrachtet


Gruß Roland

Benutzeravatar
theo
Beiträge: 9573
Registriert: Mo 11. Sep 2006, 19:01

Re: Genaue Ausrichtung von Komponenten

Beitrag von theo »

@Ally: Danke, aber wie soll das gehen, wenn die visuelle Höhe dem System offenbar nicht bekannt ist?

Benutzeravatar
Ally
Beiträge: 221
Registriert: Do 11. Jun 2009, 09:25
OS, Lazarus, FPC: Win und Lazarus Stable release
CPU-Target: x64

Re: Genaue Ausrichtung von Komponenten

Beitrag von Ally »

Hallo Theo,

ich hoffe ich verstehe dich jetzt nicht falsch.
Die Höhe von TEdit ist, zumindest unter Windows, fix.
Wenn man also Edit und Button die gleiche Höhe haben sollen, bleibt nur die Option den Button am Edit zu verankern.
Im gezeigten Beispiel oben, unten und auch gleich links (mit entsprechendem Abstand).
Man kann anschließend das Edit-Feld umpositionierenn und der Button wandert munter mit.
Wenn man das konsequent auf das gesamte Layout anwendet, verliert die Portierung auf eine andere Plattform deutlich an Schrecken.

wp_xyz
Beiträge: 4427
Registriert: Fr 8. Apr 2011, 09:01

Re: Genaue Ausrichtung von Komponenten

Beitrag von wp_xyz »

Hab's gerade in meiner VM mit OpenSUSE ausprobiert (gtk2), aber da hat ein TEdit eine Default-Höhe von 31 (AutoSize=true) und ein TButton von 25 (AutoSize=false), aber ich kann den Button beliebig in der Höhe verändern. Aber wenn ich den Button auf AutoSize=true schalte, werden 33 draus, die natürlich nicht mehr veränderbar sind. Da AutoSize = true eigentlich immer Sinn macht, würde ich, wie Ally schon sagte, die Controls im Anker-Editor aneinander ausrichten, aber nicht an den oberen Kanten, sondern an der Mitte, so dass das Edit und der Button zueinander zentriert sind.

Benutzeravatar
Ally
Beiträge: 221
Registriert: Do 11. Jun 2009, 09:25
OS, Lazarus, FPC: Win und Lazarus Stable release
CPU-Target: x64

Re: Genaue Ausrichtung von Komponenten

Beitrag von Ally »

Hallo Theo,

kleine Korrektur: Die Höhe von TEdit ist nur dann fix, wenn AutoSize True ist.
Man könnte also auch das Edit an den Button anpassen.
Da das Widgetset aber die jeweilige Standardhöhe vorgibt, würde ich die auch verwenden. (macht man es kleiner, sind dann vielleicht schnell mal die Unterlängen weg :( )

Edit: Da war wp_xyz etws schneller :)

Benutzeravatar
theo
Beiträge: 9573
Registriert: Mo 11. Sep 2006, 19:01

Re: Genaue Ausrichtung von Komponenten

Beitrag von theo »

Danke erst einmal. Das schaue ich mir später genauer an.

Benutzeravatar
theo
Beiträge: 9573
Registriert: Mo 11. Sep 2006, 19:01

Re: Genaue Ausrichtung von Komponenten

Beitrag von theo »

Danke.
Ich habe das jetzt genau so gemacht, aber auf GTK2 sind die Controls trotzdem nicht gleich hoch. Vielleicht auch Theme abhängig?
Habe den Bereich um den Button farblich etwas hervorgehoben zur Veranschaulichung.

anchoredit.png
anchoredit.png (10.77 KiB) 221 mal betrachtet

Ich möchte da eigentlich auch nicht visuell mit dem Anchor Editor pro Widget-Set herumdoktern, da ich die Komponenten im Code erzeuge.

Edit: Hmmm, ja, das hängt vom Theme ab.
Mit Breeze sieht es besser aus. Das im Bild oben ist Oxygen.
Da hat man wohl ohne Theme Services keine Handhabe.

wp_xyz
Beiträge: 4427
Registriert: Fr 8. Apr 2011, 09:01

Re: Genaue Ausrichtung von Komponenten

Beitrag von wp_xyz »

theo hat geschrieben:
Mi 23. Nov 2022, 14:40
Ich möchte da eigentlich auch nicht visuell mit dem Anchor Editor pro Widget-Set herumdoktern, da ich die Komponenten im Code erzeuge.
Wie wir hier sehen, ist es ja nicht nur PRO Widgetset, sondern sogar IM Widgetset, je nach Theme. Da führt an der Verankerung kein Weg vorbei. Du kannst natürlich auch im Code erzeugte Controls verankern: https://wiki.freepascal.org/Anchor_Sides.

Code: Alles auswählen

procedure TForm1.FormCreate(Sender: TObject);
begin
  Edit1 := TEdit.Create(self);
  Edit1.AnchorSideLeft.Control := self;
  Edit1.AnchorSideTop.Control := Self;
  Edit1.BorderSpacing.Around := 16;
  Edit1.Parent := self;

  Button1 := TButton.Create(self);
  Button1.AnchorSideLeft.Control := Edit1;
  Button1.AnchorSideLeft.Side := asrRight;
  Button1.AnchorSideTop.Control := Edit1;
  Button1.AnchorSideTop.Side := asrCenter;
  Button1.BorderSpacing.Around := 16;
  Button1.AutoSize := true;
  Button1.Caption := 'Click me';
  Button1.Parent := self;

  AutoSize := true;
end; 

Benutzeravatar
theo
Beiträge: 9573
Registriert: Mo 11. Sep 2006, 19:01

Re: Genaue Ausrichtung von Komponenten

Beitrag von theo »

wp_xyz hat geschrieben:
Mi 23. Nov 2022, 15:44
theo hat geschrieben:
Mi 23. Nov 2022, 14:40
Ich möchte da eigentlich auch nicht visuell mit dem Anchor Editor pro Widget-Set herumdoktern, da ich die Komponenten im Code erzeuge.
Wie wir hier sehen, ist es ja nicht nur PRO Widgetset, sondern sogar IM Widgetset, je nach Theme. Da führt an der Verankerung kein Weg vorbei. Du kannst natürlich auch im Code erzeugte Controls verankern: https://wiki.freepascal.org/Anchor_Sides.
Danke für deine Anteilnahme! :wink:

Aber wenn die LCL nicht weiss, wie die Höhe der Komponente wirklich/optisch/visuell ist, dann kann sie sie auch nicht ausrichten.
Wie soll das gehen, wenn "Height" nicht dem visuellen Eindruck entspricht?
Wenn "Height" dem visuellen Eindruck entspricht, dann brauche ich im Code auch keine Anchors sondern kann selber positionieren.
Es gibt ja nur "Top" und "Height", der Rest wird ziemlich sicher errechnet.

Denke ich falsch?

Habe noch mit der Unit "Themes" herum gespielt, aber die Höhe des TEdit bekommt man leider auch nicht raus.

wp_xyz
Beiträge: 4427
Registriert: Fr 8. Apr 2011, 09:01

Re: Genaue Ausrichtung von Komponenten

Beitrag von wp_xyz »

Drum meine ich, du solltest die Mitten aneinander verankern. Mitte bleibt Mitte, egal wie hoch die Controls ausfallen, und wenn der Text innerhalb der Controls vertikal zentriert ist, dann hat man alle Texte auf einer Grundlinie mit vielleicht +/- 1 pixel. Kann natürlich sein, dass die Theme-Designer da auch wieder anderer Ansicht sind und die Ränder um die Controls unterschiedlich machen oder den Text einseitig ausgeben.

Benutzeravatar
theo
Beiträge: 9573
Registriert: Mo 11. Sep 2006, 19:01

Re: Genaue Ausrichtung von Komponenten

Beitrag von theo »

OK, habe herausgefunden, was mein Problem war.

Das Hauptproblem lag in der Erstellung im Code statt im Designer.
Autosize ist ja die Standardeinstellung bei TEdit.
Direkt nach dem Createn ist Height aber noch nicht beim Wert nach dem Showen.
Wenn ich nach dem Sichtbarwerden die anderen Elemente am TEdit ausrichte, dann sieht es besser aus.

Danke an alle, die mir geholfen haben.

Benutzeravatar
theo
Beiträge: 9573
Registriert: Mo 11. Sep 2006, 19:01

Re: Genaue Ausrichtung von Komponenten

Beitrag von theo »

Noch kurz zur Veranschaulichung, worüber ich gestolpert bin:

Code: Alles auswählen

..
private
  fEdit:TEdit;    
..
procedure TForm1.FormCreate(Sender: TObject);
begin
  fEdit:=TEdit.Create(Self);
  fEdit.Parent:=Self;
  Caption:=fEdit.Height.ToString;
end;

procedure TForm1.FormShow(Sender: TObject);
begin
 Caption:=Caption+' > '+fEdit.Height.ToString;
end;  
Ergibt bei mir auf GTK2 "23 > 31"

Der kleine Unterschied mit dem Oxygen Theme ist trotzdem noch da, aber damit kann ich leben.

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 5478
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Niederösterreich
Kontaktdaten:

Re: Genaue Ausrichtung von Komponenten

Beitrag von af0815 »

Ich mache Layouting im Resize des Parent. Das komplette Initialisieren und Erstellung aller notwendigen (Sub)Forms im ersten OnActivate. Das schliesst dann mit einem Invalidate ab. So halte ich die Layouts im Griff. Weil ich (fast) nie weis, auf welche Plattform das ganze endgültig kommt. Die Frames selbst folgen dem selben Mechanismus. Im OnCreate kann man sich auch nicht auf die Daten von ClientWidth und ClientHeigh des Form's verlassen. Im ersten OnActivate sieht die Sache schon viel stabiler aus. Das sit für mich der beste Nenner zwischen Windows und den Linux Systemen.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Benutzeravatar
theo
Beiträge: 9573
Registriert: Mo 11. Sep 2006, 19:01

Re: Genaue Ausrichtung von Komponenten

Beitrag von theo »

af0815 hat geschrieben:
Mi 23. Nov 2022, 19:09
Ich mache Layouting im Resize des Parent.
Ja, das hatte ich auch gemacht für die horizontale Ausrichtung.
Dass das TEdit beim Showen aber die Höhe verändert gegenüber dem Zustand direkt nach dem Createn hatte ich nicht auf dem Schirm. Kombiniert mit der Ungenauigkeit bei gewissen Themes, hatte mich das verwirrt.

Jetzt ist es klarer.

Antworten