Anker im Forumlardesigner - wie verwenden?

Für Fragen rund um die Ide und zum Debugger
Antworten
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

Anker im Forumlardesigner - wie verwenden?

Beitrag von Timm Thaler »

Da ich ja lernfähig bin, versuche ich Objekte auf Formularen nicht absolut zu positionieren, sondern voneinander abhängig zu machen. Damit soll auch unter Linux mit anderen (meist größeren) Buttons ein ordentliches Forumlar aufgebaut werden.

Nun meckert allerdings der Formulareditor zunehmend wegen zirkulärer Abhängigkeiten rum und weigert sich, entsprechende Anker zu setzen. Um das mal zu illustrieren:

Anker-01.png
Anker-01.png (3.22 KiB) 1415 mal betrachtet


Ich setze
- das Edit "start" abhängig vom linken und oberen Rand
- darunter die Checkbox "Zufall" linksbündig und 10 Pixel unterhalb von "start"
- darunter das Edit "amp" linksbündig und 10 Pixel unterhalb von "zufall"
usw.

Funktioniert soweit. Nun will ich die Edits beschriften. Ich setze
- das Label "Startreihe" horizontal mittig und 10 Pixel links von "start"
- die weiteren Label ebenso bezogen auf die Edits, die sie beschreiben

Das geht auch erstmal gut, aber bei weiteren Änderungen oder nach Neuladen des Projekts meldet der Editor dann zirkuläre Abhängigkeiten der Labels und platziert die Labels teilweise außerhalb des Fensters, so dass ich sie mit Abschalten der Anker und händischen Eingeben der Position zurückplatzieren muss.

Ich sehe auch nicht, wo die zirkulären Abhängigkeiten auftreten, denn die Position der Labels selbst wird wiederum nirgends für andere Objekte verwendet.

Wie gehe ich am besten bei der Festlegung der Anker vor, um solche Abhängigkeiten zu vermeiden?

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

Re: Anker im Forumlardesigner - wie verwenden?

Beitrag von fliegermichl »

Das wüsste ich auch gerne.
Den Ankereditor von Lazarus hab ich noch nie kapiert.

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

Re: Anker im Forumlardesigner - wie verwenden?

Beitrag von Michl »

Obwohl ich eigentlich sehr viel händisch mache (also zur Laufzeit), ist der Ankereditor eines der wenigen WYSIWYG Tools, die ich in der IDE tatsächlich nutze. Dabei habe ich eigentlich keine Probleme mit zirkulären Abhängigkeiten. Eine einfache Regel an die ich mich halte ist z.B. immer von oben links und unten rechts aus verankern. Bei den TLabels suche ich mir zur Laufzeit das längste, an dem ich benachbarte Komponenten ausrichte (damit kein unnötiger Platz zwischen einem TLabel und TEdit ist und trotzdem alle untereinander stehen).

Bei deinem Beispiel ist ungünstig, daß du die TEdits sicherlich untereinander, gleich groß und formularfüllend haben möchtest, aber nicht immer zwei davon da sind. Wenn immer zwei da wären, würde ich ein TPanel nehmen und jeweils die zwei TEdits mittels Childsizing automatisch platzieren lassen. So wirst du die Breite eines TEdits zur Laufzeit kurz berechnen müssen:

Code: Alles auswählen

function LongestLabel(Labels: array of TLabel): TLabel;
var
  ALabel: TLabel;
  AWidth, ResultWidth: Integer;
begin
  Result := nil;
  ResultWidth := -1;
  for ALabel in Labels do
    if Assigned(ALabel) then begin
      AWidth := ALabel.Canvas.TextWidth(ALabel.Caption);
      if not Assigned(Result) or (AWidth > ResultWidth) then begin
        ResultWidth := AWidth;
        Result := ALabel;
      end;
    end;
end;
 
procedure TForm1.FormResize(Sender: TObject);
var
  ALabel: TLabel;
  AWidth: Integer;
begin
  ALabel := LongestLabel([Label1, Label2, Label3, Label4, Label5]);
  Edit1.AnchorSide[akLeft].Control := ALabel;
  AWidth := ClientWidth
            - 10 // left label space
            - ALabel.Width // longest label
            - 10 // left first edit space
            - 10 // left second edit space
            - 10; // right second edit space;
  AWidth := AWidth div 2;
  Edit1.Width := AWidth;
end

Hab mir mal die Mühe gemacht und das Bsp von dir angefügt.
Dateianhänge
Bsp.zip
(2.53 KiB) 153-mal heruntergeladen

Code: Alles auswählen

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

Antworten