Matrix aus Panels mit Inhalten

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

Matrix aus Panels mit Inhalten

Beitrag von jrx »

Hallo

ich schreib ein Programm, das im Prinzip eine Checkliste darstellt.
Das realisiere ich in dem ich Panels dynamisch erzeuge und anordne.
Auf dem Panel werden dann wiederum die ganzen "Innereien" : Labels, Checkboxen, Memo ... dynamisch erzeugt ...
Das funktioniert ganz gut, mittlerweile wächst der Quelltext aber auf ein Maß, wo die übersicht verloren geht.
Außerdem funktioniert das mit den Anchors manchmal nicht richtig, weil kontextabhängig einige Elemente ein/ausgeblendet werden müssen.

Jetzt hab ich die Idee, daß ich das 1. Panel mit dem Formulardesigner generiere und dann das dann nur 20..50x kopiert und auf einer Scrollbox angeordnet wird.
Die Elemente bekommen nur noch eine fortlaufende Nummer im Namen und zum Auslesen nehme ich den Sender, der bei OnClick oder OnChange übernommen wird.

Änderungen mach ich nur noch im Formular, sodass ich auch schnell mal was ändern könnte.

Theoretisch hört sich das gut an, aber wie ich das machen soll weiß ich leider nicht. :(
Lassen sich mit einem Rutsch Panels mit allen Ihren Kindern mittels Quelltext Kopieren?
a lá

panel := TPanel.create(self);
Panel.Name = 'pn_'+IntToStr(lfdNr);
Panel.EigenschaftenMitAllenKindern(Vorlagepanel);

Ganz so einfach wirds nicht gehen, aber ich würde gerne in einem Rutsch vor allen Dingen die Anchors, Rahmen, Abstände Schriften kopieren.

Kann mir bitte jemand einen Tipp geben?

Grüße 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: Matrix aus Panels mit Inhalten

Beitrag von pluto »

Du könntest dir logische Unter Funktionen schreiben. Die du dann öfter aufrufst. Weißt du wie ich meine?
MFG
Michael Springwald

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

Re: Matrix aus Panels mit Inhalten

Beitrag von jrx »

Ich im Prinzip ja so gemacht.
Ich erzeuge die Elemente mittels einer Schleife, die Namen haben dann den Bestandteil 'panel'+IntToStr(i).
In der Unterfunktion lege ich dann die ganzen Anchor, Schiftarten Fragen usw fest.
Auf den Panel sind aber 2xweitere Panels, 1xCheckbox, 1xMemo, 1x Checlistbox, 1xListbox, viele Labels, 1xToolbar mit 9 Toolbuttons.
In Abhängigkeit vom Programmkontext werden dann die verschiedenen Elemente xx.visible:=True/False geschalten

Schon der Quelltext zur Erzeugung der Panels hat schon fast 100 Zeilen.

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: Matrix aus Panels mit Inhalten

Beitrag von pluto »

Zeig mal ein Ausschnitt aus den Code... Dann kann man vielleicht besser helfen.
MFG
Michael Springwald

Benutzeravatar
willi4willi
Lazarusforum e. V.
Beiträge: 170
Registriert: Sa 1. Nov 2008, 18:06
OS, Lazarus, FPC: Lazarus 3.8 FPC 3.2.2 x86_64-win64-win32/win64 x86_64-linux-gtk2
CPU-Target: i386, win64, arm

Re: Matrix aus Panels mit Inhalten

Beitrag von willi4willi »

Hallo jrx,

ist das nicht einfacher zu realisieren indem man Frames verwendet?

Willi4Willi
 

Viele Grüße

Willi4Willi

------------

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

Re: Matrix aus Panels mit Inhalten

Beitrag von jrx »

Hallo Willi,
Das mit den Frames muss ich mal ausprobieren. Allerdings hab ich das Konzept noch nicht ganz verstanden.
Mein Lazarusbuch gibt auch nicht viel her. Am besten ich probiere es mal aus.

@Pluto
Quelltext:

Code: Alles auswählen

 
 
procedure TfrmMain.FormCreate(Sender: TObject);
var
  i, j: integer;
 
  procedure GenCockpit(pbyte: byte; Nr: integer); 
  var
    pn, pnCB: TPanel;
    cbCockpit: TCheckBox;
    la: TLabel;
    ...
 
  begin
    pn := TPanel.Create(self); //Hauptpanel
    case pbyte of
      1:    pn.parent := pnStudyMatrix; //panel im Formular
      ...
    pn.Name := CockpitFormStrings[CP_panel] + CockpitBez[pbyte] + '_' + IntToStrNull(Nr);
    pn.Caption := '';
    pn.BorderStyle := bsNone;
    pn.BevelInner := bvNone;
    pn.BevelOuter := bvNone;
    pn.AutoSize := False;
    pn.Hint := CockpitFormsHintStrings[CP_panel];
    pn.ShowHint := True;
    pn.OnClick := @panelClick;
 
    pnCB := TPanel.Create(self); 
    pnCB.Name := CockpitFormStrings[CP_pnCheckbox] + CockpitBez[pbyte] + '_' + IntToStrNull(Nr);
    pnCB.Parent := pn;
    pnCB.Caption := '';
    pnCB.BorderStyle := bsNone;
    pnCB.BevelInner := bvNone;
    pnCB.BevelOuter := bvNone;
    pnCB.AutoSize := True;
    pnCB.Hint := CockpitFormsHintStrings[CP_panel];
    pnCB.ShowHint := True;
    pnCB.OnClick := @panelClick;
    pnCB.Top := 0;
    pnCB.Left := 24;
    pnCB.AutoSize := True;
 
    cbCockpit := TCheckBox.Create(self); // Clickbox
    cbCockpit.Name := CockpitFormStrings[CP_cbTick] + CockpitBez[pbyte] + '_' + IntToStrNull(Nr);
    cbCockpit.Parent := pnCB;
    cbCockpit.Font.Name := MainFont;
    cbCockpit.Font.size := MainFontSize;
    cbCockpit.Font.Color := BlackText;
    cbCockpit.Checked := False;
    cbCockpit.AutoSize := True;
    cbCockpit.Top := 0;
    cbCockpit.Left := 0;
    cbCockpit.OnMouseEnter := @lMouseEnter;
    cbCockpit.OnMouseLeave := @lMouseLeave;
    cbCockpit.OnClick := @TickClick;
    cbCockpit.hint := CockpitFormsHintStrings[CP_cbTick];
    cbCockpit.showhint := True;
 
    for c := CP_laCockpitNr to CP_laPhase do
    begin   //Cockpitnummer und Phasenüberschrift
      la := TLabel.Create(self);
      la.Name := CockpitFormStrings[c] + CockpitBez[pbyte] + '_' + IntToStrNull(Nr);
      la.Parent := pnCB;
      la.Font.Name := MainFont;
      la.Font.size := MainFontSize
      la.Font.Color := BlackText;
      la.AutoSize := True;
      la.Left := 0;
      la.top := 0;
      la.OnMouseEnter := @lMouseEnter;
      la.OnMouseLeave := @lMouseLeave;
      if c = CP_laCockpitNr then
      la.OnClick := @mnuShowPhaseInfosClick;
      la.hint := CockpitFormsHintStrings[c];
      la.ShowHint := True;
      la.AnchorSideLeft.Control := cbCockpit;
      la.AnchorSideTop.Control := pnCB;
      la.AnchorSideTop.Side := asrCenter;
      la.AnchorSideLeft.Side := asrLeft;
    end;
   //... weitere Zeilen
 
  end;
 
begin
  for i := 1 to 3 do
    for j := 1 to maxColumns do
      GenCockpit(i, j);             
end;
  
Voila eine Matrix

Die Anordnung wird immer in Abhängigkeit vom Programmkontext errechnet.
Die Befüllung der .Checked, .Caption, .Text usw. erfolgt via

Code: Alles auswählen

 
    LB := TListBox(FindComponent(CockpitFormStrings[CP_liLink] + CockpitBez[PosX] + '_' + IntToStrNull(PosY)));
 
Auslesen über den Sender, wenn ich draufklicke.

Ich glaube schon, dass ich alles einigermaßen richtig mache. Ich möchte aber ein Stück mehr Bequemlichkeit.

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: Matrix aus Panels mit Inhalten

Beitrag von pluto »

Es gibt nicht viele Möglichkeiten. Z.b. könntest du mehrere Fenster erstellen und als Vorlagen verwenden. Weißt du wie ich meine?
Beispiel: Du hast nun ein Fenster erstellt, welches Komponenten enthält. Diese Komponenten kannst du jetzt einfach übernehmen in das eigentliche Fenster. z.b. in dem du sie kopierst.

In deinen Fall könnte es sich lohnen.
MFG
Michael Springwald

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

Re: Matrix aus Panels mit Inhalten

Beitrag von jrx »

Das mit dem Kopieren hab ich leider nicht verstanden.
Kannst du mir bitte ein Beispielcodeschnipsel zeigen.
Ich weiß nicht, wie ich dann auf die Komponenten zugreifen kann und vermute auch, daß die Anchors nicht mehr richtig funktionieren, weil sich ja der Namen von Parent, sibbling... ändert.
jrx

Benutzeravatar
willi4willi
Lazarusforum e. V.
Beiträge: 170
Registriert: Sa 1. Nov 2008, 18:06
OS, Lazarus, FPC: Lazarus 3.8 FPC 3.2.2 x86_64-win64-win32/win64 x86_64-linux-gtk2
CPU-Target: i386, win64, arm

Re: Matrix aus Panels mit Inhalten

Beitrag von willi4willi »

Hallo jrx,

mit TFrame ist soetwas recht einfach.

Versuche doch einmal folgendes:

- erstelle neues Projekt
- erstelle ein Frame (Datei --> Neu --> Frame)
- pack Deine Komponenten auf das Frame (Z.B. eine GroupBox, ein TLabel, eine TEdit, TListbox, usw.)
- setze Eigenschaften usw. vom Frame und Komponenten, wie Du es bei einem Formular machst
- speichere alles in einem Ordner ab (Projekt, Unit1= Formular, Unit2=Frame)

Wenn Du jetzt den Frame dem Formular (Toolbar --> Standard --> TFrame) hinzufügen möchtest, klappt es noch nicht (bei mir jedenfalls). Füge darum im Formular-Unit (unit1) die Frame-Unit (unit2) hinzu.

Jetzt kannst Du Deinem Formular das Frame auf dieser Weise beliebig oft hinzufügen:

- in der Toolbar TFrame auswählen und auf das Formular klicken
- im Fenster "Select Frame" das Unit2 auswählen

Oder Du machst das programmtechnisch.

Beispiel:
- Scrollbox und zwei Buttons aufs Formular ziehen
- und folgenden Code ausprobieren

Code: Alles auswählen

 
unit Unit1;
 
{$mode objfpc}{$H+}
 
interface
 
uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
  unit2;
 
type
 
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    ScrollBox1: TScrollBox;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    links, oben : integer;  // Position merken
  public
    MyFrameArray : array of TFrame1;     // Feld aus Frames
  end;
 
var
  Form1: TForm1;
 
implementation
 
{$R *.lfm}
 
procedure TForm1.FormCreate(Sender: TObject);
begin
  links:=10; //hier geht es los
  oben:=10;
end;
 
procedure TForm1.Button1Click(Sender: TObject);  // Frame erzeugen
begin
  setlength(MyFrameArray,length(MyFrameArray)+1);  // Feld vergrößern
  MyFrameArray[length(MyFrameArray)-1]:=TFrame1.Create(self); // Frame erzeugen
  MyFrameArray[length(MyFrameArray)-1].Name:='Frame_'+IntToStr(length(MyFrameArray)); // die Taufe
  MyFrameArray[length(MyFrameArray)-1].GroupBox1.Caption:=MyFrameArray[length(MyFrameArray)-1].Name; // (mein Frame hat eine Groupbox)
  MyFrameArray[length(MyFrameArray)-1].Parent:=ScrollBox1; // Adoptiv-Eltern
  MyFrameArray[length(MyFrameArray)-1].Left:=links;   // Geburtsort
  MyFrameArray[length(MyFrameArray)-1].top:=oben;
  MyFrameArray[length(MyFrameArray)-1].Show;          // da ist es !!
  links:=MyFrameArray[length(MyFrameArray)-1].Left+MyFrameArray[length(MyFrameArray)-1].Width+10;  // nächste Position festlegen
end;
 
procedure TForm1.Button2Click(Sender: TObject); // ... und wieder löschen
begin
  if length(MyFrameArray)>0 then   // nur wenn Frames da sind
  Begin
    links:=MyFrameArray[length(MyFrameArray)-1].Left;  //Position zurücksetzen
    FreeAndNil(MyFrameArray[length(MyFrameArray)-1]); // Frame zerstören
    setlength(MyFrameArray,length(MyFrameArray)-1);  // Feld verkleinern
  end;
end;
 
end.
 
 

Jrx, ist es das was Du suchst?

Viele Grüße

Willi4Willi
 

Viele Grüße

Willi4Willi

------------

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

Re: Matrix aus Panels mit Inhalten

Beitrag von jrx »

Danke.
Ich glaube, daß ist das was ich suche.

Wieder was dazugelernt :-)

Antworten