Ausrichten in dynamisch erzeugtem Formular

Rund um die LCL und andere Komponenten
Antworten
jrx
Beiträge: 49
Registriert: Fr 14. Mai 2010, 13:23
OS, Lazarus, FPC: Win/UX
Wohnort: Erlangen

Ausrichten in dynamisch erzeugtem Formular

Beitrag von jrx »

Hallo zusammen.

Ich möchte auf einem Panel eine Reihe von TCheckboxen erzeugen.
In 3 Spalten, manchmal gibt es einen größeren Abstand dazwischen:
á la

Code: Alles auswählen

[ ]#### ### ####   [ ]#### #### [ ]#### ####
[ ]#### ### ###    
[ ]#### ### ## ### [ ]####      
                   [ ]#### #    [ ]#### ####
[ ]#### ### #      [ ]# # ###   [ ]#### ####
Die ## sollen Text darstellen.

Code: Alles auswählen

procedure TForm1.FormCreate(Sender: TObject) ;
var
   i, LeftPosi, TopPosi, len: Integer ;
   cb: TCheckBox ;
begin
   FillMatrix; // Matrix bekommt seine Werte
   LeftPosi:=12; //linker Rand
   TopPosi:=-1; //Oben, in meiner Matrix hat jede Checkbox einen Ofset = 1 zum Vorgänger
   len:=0; //soll die längste CheckboxLänge speichern 
   for i:= 0 to MaxTag do begin
      TopPosi:=TopPosi+Matrix[i].Ofs; //ofs ist 1 bei norm. Abstand, >für entspr. Lücken
      cb:=TCheckBox.Create(self); //anlegen
      with cb do begin
         Parent:=panel1; 
         AutoSize:=True; 
         Caption:=Matrix[i].Cap; //unterschiedliche Bezeichnungen
         Checked:=Matrix[i].Tick;
         Name:='cb'+Matrix[i].Tag;
         if Width>len Then len:=Width; //das längste soll gespeichert werden
         Top:=TopPosi*Height;
         Left:=LeftPosi;
         if Width>=len Then len:=Width;
      end;
 
      if i=10 then begin  //2. Spalte 
         LeftPosi:=LeftPosi+len+12; // verschieben des linken Randes
         TopPosi:=-1;len:=0;   // "reset", nächste Spalte begint oben
      end;
      if i=21 then begin  //3. Spalte
         LeftPosi:=LeftPosi+len+12;
         TopPosi:=-1;
      end; 
 
  end ;
end;
Das funktioniert soweit ganz gut. Die 3 Spalten werden gebildet und auch der (unregelmäßig) Abstand der Checkboxen wird richtig erzeugt.
Problem ist, daß der linke Rand der 2. und 3. Spalte nicht paßt. Offensichtlich bekommt die variable "len := cb.width;" nicht den richtigen Wert.
Die Spalten sind ausgerichtet, allerdings zu schmal. cb.autosize := True oder False hat auch keinen Einfluß.

Woran kann denn das liegen?

Danke für eure Hilfe
jrx

Scotty
Beiträge: 768
Registriert: Mo 4. Mai 2009, 13:24
OS, Lazarus, FPC: Arch Linux, Lazarus 1.3 r44426M FPC 2.6.4
CPU-Target: x86_64-linux-qt/gtk2
Kontaktdaten:

Re: Ausrichten in dynamisch erzeugtem Formular

Beitrag von Scotty »

Ohne groß durch deinen Code zu sehen, kann ich die Lazarus interne Verankerung empfehlen: http://wiki.lazarus.freepascal.org/Autosize_/_Layout" onclick="window.open(this.href);return false; (insbesondere Absatz "Anchored to sibling").

jrx
Beiträge: 49
Registriert: Fr 14. Mai 2010, 13:23
OS, Lazarus, FPC: Win/UX
Wohnort: Erlangen

Re: Ausrichten in dynamisch erzeugtem Formular

Beitrag von jrx »

Hallo Scotty

bisher hab ich ja meine Formulare gebastelt und die ganzen Anchors im Formulareditor gesetzt.
Das geht solange gut, wie das Formular sich nicht ändert, weil eine Checklistbox dazukommt usw.
Deshalb möchte ich auch mein Formular dynamisch erzeugen, hier einen Fragebogen.

Die Definition der Anchors mittels Programmierung erscheint mir zu aufwändig. weil die Positionen ja während der Laufzeit errechnet werden.
Beim Parent-Panel aus dem Hauptprogramm greife ich wieder auf den Formulareditor zurück.

Weiterhin gibts ja bei einigen Zeilen Lücken und auch die fixe Definition if i=10.. und if i=20 .. für die neue Spalte sollen eigentlich dynamisch sein.
Da wird's auch mit AnchorToNeighbour, Sibling usw. schwierig.

Warum wird cb.width nicht richtig ermittelt und deshalb cb.Left nicht richtig gesetzt?

Hab ich vielleicht einen prinzipiellen Fehler in meiner Denke?
jrx

pluto
Lazarusforum e. V.
Beiträge: 7192
Registriert: So 19. Nov 2006, 12:06
OS, Lazarus, FPC: Linux Mint 19.3
CPU-Target: AMD
Wohnort: Oldenburg(Oldenburg)

Re: Ausrichten in dynamisch erzeugtem Formular

Beitrag von pluto »

Auf den ersten Blick, kann ich nur sagen: In Etwa würde ich das genau so machen. Kannst du mal eine ScrennShot machen?

Von der Logik her stimmt jedenfalls alles. Würde ich behaupten.

edit01: du könntest mit Canvas.TextWidht die Pixel Größe selbst ermitteln. Eine CheckBox sollte sowas haben.
MFG
Michael Springwald

jrx
Beiträge: 49
Registriert: Fr 14. Mai 2010, 13:23
OS, Lazarus, FPC: Win/UX
Wohnort: Erlangen

Re: Ausrichten in dynamisch erzeugtem Formular

Beitrag von jrx »

Hallo,

ich hab den ganzen Tag gegrübelt.
Wenn ich die "Anordnefunktionen" von den "create"-Funktionen trenne, dann gehts.
Offensichtlich konnen in TForm.Create die "Abmaße" der Zeichenketten noch nicht richtig ermittelt werden. :!:
Das Objekt muß "richtig" fertig sein. - ich brauche also zwei loops;

Ich habs also jetzt so:

Code: Alles auswählen

Procedure CreateFragebogen;
:
cb := TCheckbox.Create(self) ...
cb.name := 'cb'+matrix[i].tag
:
 
 
Procedure UpdateFragebogen;
:
for i:=0 to ...
   cb := TCheckbox(FindComponent('cb'+matrix[i].tag));
   cb.width := ...
:
Jetzt zappelt mein Formular allerdings etwas.
Grüße jrx

DiBo33
Beiträge: 334
Registriert: Do 11. Okt 2007, 18:01

Re: Ausrichten in dynamisch erzeugtem Formular

Beitrag von DiBo33 »

Und wenn du die Initialisierung in OnActivate statt ins OnCreate packst? in dem Moment sind eigentl. alle Maße bekannt.

In der OnActivate-Procedure setzt du OnActivate auf nil, damit diese nur einmal aufgerufen wird.

pluto
Lazarusforum e. V.
Beiträge: 7192
Registriert: So 19. Nov 2006, 12:06
OS, Lazarus, FPC: Linux Mint 19.3
CPU-Target: AMD
Wohnort: Oldenburg(Oldenburg)

Re: Ausrichten in dynamisch erzeugtem Formular

Beitrag von pluto »

Warum wird cb.width nicht richtig ermittelt und deshalb cb.Left nicht richtig gesetzt?
lass, dir doch mal ausgeben, was da drin steht "cb.width".
MFG
Michael Springwald

jrx
Beiträge: 49
Registriert: Fr 14. Mai 2010, 13:23
OS, Lazarus, FPC: Win/UX
Wohnort: Erlangen

Re: Ausrichten in dynamisch erzeugtem Formular

Beitrag von jrx »

ich hab's ins Onactivate verschoben, da ging's, auch nur, wenn schon alle checkboxes fertig waren, also auch nur die 2-loop-Lösung.
Die Länge war ('optisch') die Länge, wenn "Checkbox1" stehen würde.
obwohl .caption schon einen neuen Wert bekommen hatte.
schönes Wochenende. jrx

pluto
Lazarusforum e. V.
Beiträge: 7192
Registriert: So 19. Nov 2006, 12:06
OS, Lazarus, FPC: Linux Mint 19.3
CPU-Target: AMD
Wohnort: Oldenburg(Oldenburg)

Re: Ausrichten in dynamisch erzeugtem Formular

Beitrag von pluto »

ich hab's ins Onactivate verschoben, da ging's, auch nur, wenn schon alle checkboxes fertig waren, also auch nur die 2-loop-Lösung.
Ein Komisches Verhalten. Ich selbst hatte auch schon öfter Probleme mit ähnlichen Fällen, die Lösung war das meistens es in ein anderen Event zu packen und dafür zu sorgen das es nur einmal ausgeführt wird.
MFG
Michael Springwald

Antworten