Komme nicht klar: Dynamisches Layout mit Lazarus

Rund um die LCL und andere Komponenten
DR. Volker Jaenisch
Beiträge: 4
Registriert: Do 6. Aug 2015, 02:32

Komme nicht klar: Dynamisches Layout mit Lazarus

Beitrag von DR. Volker Jaenisch »

Servus!

Ich verzweifle an mir und Lazarus bei dynamischen Layouts.

Die Aufgabe:

Ich möchte 2x2 Panels, welche dynamisch den maximalen Raum der Form ausfüllen.
Jedes Panel enhält :
* eine Group-Box in der sich ein TDBEdit und ein Button horizontal angeordnet befinden.
* darunter ein TDBImage, welches mittels Stretch und Proportional ein Bild in den verfügbaren Raum einpasst.

Ich bin mir noch nicht sicher ob ich den Layout Algorithmus der LCL richtig verstanden habe. Daher berichte ich, was ich glaube verstanden zu haben und Ihr erklärt mir, was ich falsch verstanden habe.

* Die LCL arbeitet gewöhnlich beim autosizing von innen nach außen. Stelle ich bei einer Komponente autoSize auf True bedeutet dies, dass diese Komponente sich an den Dimensionen deren Inhalts orientiert.
* Weiterhin bietet die LCL die Möglichkeit von Außen nach innen vorzugehen über das ChildSizing. Hierbei werden Spielregeln vorgegeben, wie Unterkomponenten relativ zur Oberkomponente skaliert werden.

Die Strategie für mein Problem ist auch klar. Zunächst per Child-Sizing von außen die Größe der Subkomponenten ermitteln, dann in den Sub-Komponenten welche nun von Außen eine Größe zugewiesen bekommen haben, die Bilder per Stretch darstellen.
Das bedeutet, dass bei allen Komponenten auf jeder Ebene Autosize:=False sein muss. Sonst würde das Bild "ausbrechen" und seine Größe von Innen nach außen durchdrücken.

Damit sollten eigentlich alle Bausteine vorhanden sein um das gegebene Problem zu lösen. Wenn ich z.B: GroupBoxen 2x2 per child-Sizing in ein Panel packe ist alles prima. Ich bekomme vier Groupboxen, welche den verfügbaren Platz ausnutzen.

Bild

Sobald ich aber in eine der Group-Boxen einen Inhalt einfüge verändert sich das Layout:

Bild

Und das verstehe ich einfach nicht:
* GroupBox1 ist nicht autoSize=True, passt sich also nicht dem Inhalt an. Daher sollte GroupBox1 weiterhin bestimmt sein von der ChildSizing-Regel des umschließenden Panels.

Wenn so ein triviales Beispiel zu unvorhersehbarem Ergebnis führt, ist es kein Wunder, dass die kompliziertere Anforderung nicht erfüllt werden kann. Die Frage die sich mir stellt ist: Wo ist die Grenze zwischen Top-Down und Bottom-UP beim Algorithmus für das Layout.

Ich bastele an diesem Problem schon einige Tage und habe viel dazu gelesen. Aber trotzdem bekomme ich es ums verrecken nicht hin, selbst einfachste dynamische Layouts zu bauen. Sicher mache ich irgendwas grundlegendes falsch.

Beste Grüße

Volker

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6198
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:

Re: Komme nicht klar: Dynamisches Layout mit Lazarus

Beitrag von af0815 »

Ist der Artikel Anchor_Docking bekannt ?

Andi
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Michl
Beiträge: 2505
Registriert: Di 19. Jun 2012, 12:54

Re: Komme nicht klar: Dynamisches Layout mit Lazarus

Beitrag von Michl »

Wenn ich dich richtig verstanden habe, suchst du die Eigenschaft Anchors. Damit kannst du alle Componenten miteinader verknüpfen. Anbei ein Bsp., wie ich es verstanden habe, wie du es willst (ich habe keine DB-Controls verwendet - könnten aber einfach ersetzt werden).

Ich definiere nur die Größe des ersten Panels, alle anderen richten sich danach aus:

Code: Alles auswählen

procedure TForm1.FormChangeBounds(Sender: TObject);
begin
  Panel1.Width := ClientWidth div 2;
  Panel1.Height := ClientHeight div 2;
end;
 
procedure TForm1.FormShow(Sender: TObject);
begin
  FormChangeBounds(nil);
end;

Bsp. anbei.

PS: ich nutze zumeist die Möglichkeit in so einem Fall die Panels mit TSplitter zu trennen, damit kann der Nutzer zur Laufzeit seine Größe der Panels selbst bestimmen.
Dateianhänge
TestAnordnung.zip
(457.19 KiB) 114-mal heruntergeladen

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection; 

DR. Volker Jaenisch
Beiträge: 4
Registriert: Do 6. Aug 2015, 02:32

Re: Komme nicht klar: Dynamisches Layout mit Lazarus

Beitrag von DR. Volker Jaenisch »

Servus!
af0815 hat geschrieben:Ist der Artikel Anchor_Docking bekannt ?

Andi


Ja und verstanden glaube ich auch. Ich verstehe nur nicht wie ich damit das gegebene Problem lösen soll?

Ich nehme ich zwei Komponenten und verankere die erste links/oben an der Form. Die zweite verankere ich an der ersten auf der rechten Seite und oben/rechts an der Form.

Verändere ich nun die Größe der Form, so skaliert nur die rechte Komponente mit der Form. Die linke bleibt auf der Design-Größe.

Das entspricht aber nicht dem gewünschten Verhalten eines homogenen Skalierens beider Komponenten mit der Form.

Oder war Dein Post so zu verstehen, dass ich eine andere Layout Technik und das Anchoring kombinieren soll ?

Beste Grüße

Volker

DR. Volker Jaenisch
Beiträge: 4
Registriert: Do 6. Aug 2015, 02:32

Re: Komme nicht klar: Dynamisches Layout mit Lazarus

Beitrag von DR. Volker Jaenisch »

Servus!

Michl hat geschrieben:Ich definiere nur die Größe des ersten Panels, alle anderen richten sich danach aus:[code=laz]procedure
TForm1.FormChangeBounds(Sender: TObject);
begin
Panel1.Width := ClientWidth div 2;
Panel1.Height := ClientHeight div 2;
end;


Das war der Baustein, der mir gefehlt hat. Ich war davon ausgegangen dieses Problem ohne Code schreiben zu müssen lösen zu können. Diese Annahme war offenbar falsch.

Vielen, vielen Dank für die schnelle Antwort und das Testbeispiel.

Beste Grüße

Volker

Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 1432
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Lazarus Fixes FPC Stable
CPU-Target: 32/64Bit
Wohnort: Echzell

Re: Komme nicht klar: Dynamisches Layout mit Lazarus

Beitrag von fliegermichl »

Das geht auch ohne Code.
Die Lazarusentwickler haben sich ne Menge Arbeit mit dem Thema gemacht.

Um das zu erreichen was du willst, setze in der Eigenschaft Childsizing des Formulares die Untereigenschaft
ControlsPerLine auf 2, EnlargeVertical und EnlargeHorizontal auf crsHomogenousChildResize und Layout auf cclLeftToRightThenTopToBottom.

Gute Beschreibung mit vielen Beispielen findet sich im Wiki.

Viele Grüße
Michael

ErnstVolker
Beiträge: 327
Registriert: Di 17. Feb 2009, 10:44
OS, Lazarus, FPC: Winux (L 0.9.xy FPC 2.2.z)
CPU-Target: xxBit

Re: Komme nicht klar: Dynamisches Layout mit Lazarus

Beitrag von ErnstVolker »

Hallo,
ich habe gerade ein ähnliches Problem. Ich hätte gerne, dass sich ein Formular beim Vergrößern (man zieht an der Ecke unten rechts) entsprechend proportional verhält, d.h. Textboxen, Comboboxen etc. -hier zum "Befüllen" von Datentabellen- mitvergrößern; auch die Schrift in den Feldern.
ControlsPerLine auf 2, EnlargeVertical und EnlargeHorizontal auf crsHomogenousChildResize und Layout auf cclLeftToRightThenTopToBottom.
Das habe ich mit vier Edit-Feldern mal probiert. Funktioniert, bist auf die Vergrößerung des Textes.

Gibt es für Lazarus "Sizer" wie man sie aus dem wxFormbuilder, glade oder dem Qt-Designer kennt? Das fand ich Anfangs ziemlich bucklig, aber mit den Anchors komme ich noch schlechter zurecht. Gerade wenn man noch Labels zum Beschriften der DBLookupComboboxen hat. Wenn die Dinger per se schon mal gelabelt wären wie bei TLabeldEdit wäre ein Vorteil.

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

Re: Komme nicht klar: Dynamisches Layout mit Lazarus

Beitrag von wp_xyz »

Vergiss TLabeledEdit, das hat so viele Unwägbarkeiten.

Um ein Label optimal an ein Control auszurichten und so mit dem Control zu verbinden, dass es den Control folgt, wenn dieses verschoben wird, brauchst du den Anker-Editor:
  • Ich nehme an, das Label soll linksbündig über der DBLookupCombobox liegen.
  • Öffne den Anker-Editor, und lasse ihn immer offen (das ist ein Vorteil der alten ungedockten IDE, weil man da den Ankereditor immer bequem neben das Formular schieben kann).
  • Wähle im Formulardesigner das Label aus.
  • Im Anker-Editor, linke Box "Linke Verankerung": Wähle in der Combobox die DBLookupCombo aus, drücke den linken Speedbutton für die linksbündige Ausrichtung und versichere dich, dass die Checkbox "Eingeschaltet" markiert ist --> damit ist die linke Seite des Labels mit der linken Seite der DBLookupCombo verbunden. Wenn du das DBLookCombo horizontal verschiebst, folgt das Label. Das Label selbst kannst du nicht mehr verschieben, nur noch vertikal, aber das liegt daran, dass wir die vertikale Position noch nicht behandelt haben.
  • Nochmals das Label markieren. Nun im Anker-Editor zur Box "Untere Verankerung" (denn wir wollen die untere Seite des Labels verankern, "Eingeschaltet" auf true, in der Combobox wieder das DBLookuCombo auswählen und die oberen Speedbutton aktivieren - dieser bedeutet, dass die untere Seite ÜBER der DBLookupCombo liegen soll; ich finde das Icon sagt alles dazu. Nun wird wahrscheinlich das Label an derselben Stelle bleiben - das liegt daran, dass per Default noch die "obere Verankerung" eingeschaltet ist. Sobald du die dortige Checkbox "Eingeschaltet" deaktivierst und die obere Seite des Labels freigibst, springt das Label genau über die DBLookupCombo.
  • Mir ist noch solchen Aktionen immer der Abstand zwischen Label und Control zu klein. Das kannst du mit den Zahlenwerten in der Box "Randbreite" einstellen - vergrößere den obere Wert und du siehst, wie das Label vom DBLookupCombo wegwandert. Oder ändere die BorderSpacing-Werte im Objekt-Inspektor (das ist dasselbe).
  • Wenn du nun das DBLookupCombo irgendwo hin bewegst, folgt das Label exakt und in jeder Richtung.
In Michl's neuem DockedFormEditor geht es etwas schneller, aber da ändert sich die Bedienung fast noch täglich, so dass ich hier keine Schritt-für-Schritt-Anleitung geben möchte. Außerdem musst du zunächst das Prinzip der Verankerung verstanden haben, was du am besten mit dem alten Anker-Editor lernst.

Wenn du mit Autosize des Containers arbeitest, muss du in der Regel darauf achten, dass die Positionen aller Control durch Verankerung fixiert sind, sonst fliegen die noch frei beweglichen Controls in die linke obere Ecke. In dem Beispiel mit Label über DBLookupCombo, ist die LookupCombo das frei bewegliche Control. Du musst seine untere Seite an die unsere Seite des Containers fixieren, damit es beim AutoSize des Containers an der richtigen Stelle bleibt. Angenommen Label und DBLookupCombo befinden sich in einem Panel, und du möchtest das Panel.AutoSize aktivieren. Bevor du das machst, verankere wie oben beschrieben das Label an DBLookupCombo. Dann wähle die DBLookupCombo, gehe zum Anker-Editor, löse den oberen Anker ("Obere Verankerung" > "Eingeschaltet" aus) und setze die unter Verankerung: "Untere Verankerung" > "Eingeschaltet" ein, klicke in der Button-Gruppe der unteren Verankerung auf den unteren Button, so dass die unteren Seiten von DBLookupCombo und Panel miteinander verbunden sind. Nun kannst du Panel.AutoSize aktivieren, und das Panel wird exakt die Gruppe aus label und DBLookupCombo umschließen. (Hinweis: die linke Verankerung der DBLookupCombo habe ich hier nicht gesetzt, weil das Control sowieso an den linken Rand verschoben werden soll).

In der obigen Beschreibung was das DBLookupCombo das zentrale Control, von dem alles ausgegangen ist. Man kann aber auch anders vorgehen (und das ist oft klarer), nämlich von links nach rechts und von oben nach unten. Hier würdest du die linke Seite des Labels an die linke Seite des Containers (Panel or Form) verankern, genauso die linke Seite des DBLookupCombo an die linke Seite des Containers oder an die linke Seite des labels. Dann die obere Seite des label an die obere Seite des Containers (Gruppe "Obere Verankerung" des Labels) und die obere Seite der DBLookupCombo an die untere Seite des Labels ("Gruppe "untere Verankerung" der DBLookupCombo).

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

Re: Komme nicht klar: Dynamisches Layout mit Lazarus

Beitrag von wp_xyz »

ErnstVolker hat geschrieben:
Mi 17. Feb 2021, 12:29
Gibt es für Lazarus "Sizer" wie man sie aus dem wxFormbuilder, glade oder dem Qt-Designer kennt?
Ja, da musst du hier im Forum suchen, so eine Unit wurde hier einmal vorgestellt. Du musst dir aber klar sein, dass die Skalierung der Schriftgröße viele Benutzer vor den Kopf stößt - das ist einfach unüblich: Wenn ich ein Formular vergrößere, dann weil ich mehr sehen und nicht die Schrift größer haben will. Wenn die Schrift generell zu klein ist, dann muss das halt außerhalb deines Programms in den entsprechenden Systemeinstellungen angepasst werden. Und wenn nur speziell bei deinem Programm die Schrift zu klein ist, dann hast du an den Font-Größen herumgespielt, was man auch nicht tun sollte...

ErnstVolker
Beiträge: 327
Registriert: Di 17. Feb 2009, 10:44
OS, Lazarus, FPC: Winux (L 0.9.xy FPC 2.2.z)
CPU-Target: xxBit

Re: Komme nicht klar: Dynamisches Layout mit Lazarus

Beitrag von ErnstVolker »

Das mit dem "mehr sehen" ist doch gerade der Knackpunkt. Ich ziehe das Formular größer und die Textlabels oder der Inhalt von Comboboxen vergrößern sich mit. Ein größeres Formular nimmt ja auch wieder mehr Fläche auf dem Bildschirm ein. Deshalb versuche ich eigentlich so kompakt wie möglich zu bleiben. Mit den Standarteinstellungen an Schriften etc. Ich komme mit den Grundeinstellungen von Lazarus klar, kein Problem. Ich habe aber einen Kollegen, dem wird das zu klein sein. Ihm war das Standart-Excel-Formular schon zu klein. Die Anderen arbeiten mit der Standartgröße.

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

Re: Komme nicht klar: Dynamisches Layout mit Lazarus

Beitrag von wp_xyz »

ErnstVolker hat geschrieben:
Mi 17. Feb 2021, 18:33
Ich ziehe das Formular größer und die Textlabels oder der Inhalt von Comboboxen vergrößern sich mit.
Wie das denn? Wenn ich ein Formular größer ziehe, bleibt die Schrift gleich groß, aber die Controls bekommen mehr Platz, z.B. sieht man nun in dem Texteditor die volle Textbreite. Oder reden wir aneinander vorbei?

Timm Thaler
Beiträge: 1224
Registriert: So 20. Mär 2016, 22:14
OS, Lazarus, FPC: Win7-64bit Laz1.9.0 FPC3.1.1 für Win, RPi, AVR embedded
CPU-Target: Raspberry Pi 3

Re: Komme nicht klar: Dynamisches Layout mit Lazarus

Beitrag von Timm Thaler »

Aber genau dafür gibts doch die Defaulteinstellungen und die Windows-weite Schriftgrößenanpassung.

Wenn Du versuchst das "von Hand" selbst zu machen fliegt Dir das spätestens um die Ohren wenn der User einen 4k-Monitor mit HiDPI hat. Hab das mal für eine sauteure Spezialsoftware gesehen: Super stylische Oberfläche - nur leider war auf dem Monitor nix zu lesen und die Buttons waren winzig klein. Aber viel Platz.

Ich war auch immer der Typ "Pixelgenau selbst platzieren". Spätestens mit Win/Linux crosscompile hab ich mir das abgewöhnt, der Aufwand das für mehrere Systeme anzupassen ist einfach zu hoch.

ErnstVolker
Beiträge: 327
Registriert: Di 17. Feb 2009, 10:44
OS, Lazarus, FPC: Winux (L 0.9.xy FPC 2.2.z)
CPU-Target: xxBit

Re: Komme nicht klar: Dynamisches Layout mit Lazarus

Beitrag von ErnstVolker »

Hallo,
ich habe im ANhang mal zwei Bildchen. "EditKlein"
EditKlein.JPG
EditKlein.JPG (15.73 KiB) 2192 mal betrachtet
und "EditGroß"
EditGroß.JPG
EditGroß.JPG (20.35 KiB) 2192 mal betrachtet
Beim Größeren habe ich einfach das Formular an der Ecke gepackt und aufgezogen. Die Schriftgrößen in den Editierfeldern sind aber gleich geblieben. Der Text "Edit1" ... "Edit4" wird beide male in Größe 9 dargestellt. Ich wollte durch das Aufziehen des Formulares -da hab' ich mich in dem vorigen Beitrag falsch ausgedrückt- erreichen dass sich die Textboxen vergrößern und gleichzeit auch der Inhalt. So, dass "Edit1" bis "Edit4" nicht in Schriftgröße 9 sondern in 16 oder so dargestellt wird. Einfach damit Menschen die etwas schlechter sehen sich das über die Formulargröße anpassen können. Das will ich erreichen.
Timm Thaler hat geschrieben:
Mi 17. Feb 2021, 19:55
Aber genau dafür gibts doch die Defaulteinstellungen und die Windows-weite Schriftgrößenanpassung.
Wie gebe ich das dem Formular bzw. seinen Kindern mit?

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

Re: Komme nicht klar: Dynamisches Layout mit Lazarus

Beitrag von wp_xyz »

ErnstVolker hat geschrieben:
Do 18. Feb 2021, 11:00
So, dass "Edit1" bis "Edit4" nicht in Schriftgröße 9 sondern in 16 oder so dargestellt wird. Einfach damit Menschen die etwas schlechter sehen sich das über die Formulargröße anpassen können. Das will ich erreichen.
Das soll nicht dein Problem sein. Wenn du Standardschriftgröße verwendest und jemand sieht das nicht gut, dann hat er/sie auch Probleme mit anderen Programmen und sollte die Systemeinstellungen verändern.

Durch Änderung der Schriftgröße mit dem Formular bleibt der sichtbare Inhalt in den Edit-Feldern unverändert, und du nimmst allen anderen Benutzern deines Programms die Möglichkeit, durch Vergrößerung des Formulars mehr von den Texten zu Gesicht zu bekommen.

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

Re: Komme nicht klar: Dynamisches Layout mit Lazarus

Beitrag von wp_xyz »

ErnstVolker hat geschrieben:
Do 18. Feb 2021, 11:00
Timm Thaler hat geschrieben:
Mi 17. Feb 2021, 19:55
Aber genau dafür gibts doch die Defaulteinstellungen und die Windows-weite Schriftgrößenanpassung.
Wie gebe ich das dem Formular bzw. seinen Kindern mit?
Gar nicht, denn wenn du LCLScaling verwendest, passt es sich automatisch an. Allerdings: Falls du zu den Usern gehörst, die sich weigern, von Lazarus Version 0.8.4 aufzurüsten, kann ich dir nicht helfen. LCLScaling benötigt v1.8.x, und die Skalierung des ImageListen v2.0.x

Antworten