Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Delphi Anordnen von zur Laufzeit erzeugten Komponenten (hier Button) (https://www.delphipraxis.net/210340-anordnen-von-zur-laufzeit-erzeugten-komponenten-hier-button.html)

Blitzschutz1 7. Apr 2022 19:03

Anordnen von zur Laufzeit erzeugten Komponenten (hier Button)
 
Liste der Anhänge anzeigen (Anzahl: 1)
Ich stehe gerade mächtig auf dem Schlauch...
Es werden 10 Button in einer schleife erzeugt, die in 5 Spalten und zwei Zeilen angeodnet werden sollen (es können aber auch 15 Button in 5 Spalten und drei Zeilen usw. sein). Das Button-Array ist als dynamisch deklariert. CONST_SOUNDBUTTONS ist derzeit 10.

Code sieht wie folgt aus:
Delphi-Quellcode:
var i, zeile, spalte: Integer;
    AbstandX, OffsetX: Integer;
    AbstandY, OffsetY: Integer;
begin

  SetLength(MyBtns, 0);

  AbstandX := 10; // Abstand der einzelnen Spalten
  OffsetX := 25; // Abstand der ersten Spalte von links

  AbstandY := 20; // Abstand der einzelnen Zeilen
  OffsetY := 100; // Abstand der ersten Zeile von oben

  zeile := 0;
  spalte := 0;

  for i := 0 to CONST_SOUNDBUTTONS - 1 do
  begin
    SetLength(MyBtns, Length(MyBtns) + 1);

    MyBtns[Length(MyBtns)-1] := TButton.Create(NIL);
    MyBtns[Length(MyBtns)-1].Parent := TabSheet2;
    MyBtns[Length(MyBtns)-1].Name   := 'btnSound' + IntToStr(i);
    //MyBtns[Length(MyBtns)-1].Caption := 'Sound ' + IntToStr(i+1);

    // nur zum Ansehen der aktuellen Spalten- und Zeilenwerte
    MyBtns[Length(MyBtns)-1].Caption := IntToStr(spalte) + '|' +
                                        IntToStr(zeile);


    MyBtns[Length(MyBtns)-1].Height := 25;
    MyBtns[Length(MyBtns)-1].Width  := 75;


    MyBtns[Length(MyBtns)-1].Left :=
      spalte * (AbstandX + MyBtns[Length(MyBtns)-1].Width) + OffsetX;

    MyBtns[Length(MyBtns)-1].Top :=
      zeile * (AbstandY + MyBtns[Length(MyBtns)-1].Height) + OffsetY;


    if ((i MOD 4 = 0) AND (i > 0)) then
    begin
      spalte := 0;
    end
    else
    begin
      Inc(spalte);
    end;

    if i MOD 5 = 0 then
    begin
      Inc(zeile);
    end;

  end;
end;
Meine Frage: Was mache ich falsch. Wo ist mein Denkfehler. Rauskommen tut derzeit siehe Bild...

DevidEspenschied 7. Apr 2022 19:14

AW: Anordnen von zur Laufzeit erzeugten Komponenten (hier Button)
 
Hmm ich würde alles in ein FlowPanel packen und damit hast du die beste Kontrolle über Ausrichtung und Größe der enthaltenen Buttons:

https://docwiki.embarcadero.com/Libr...rls.TFlowPanel

BerndS 7. Apr 2022 20:17

AW: Anordnen von zur Laufzeit erzeugten Komponenten (hier Button)
 
Du machst es dir unnötig kompliziert.
I ist schon der Index für das Array und das Array kann man am Anfang gleich auf die richtige Länge setzen.
Wenn man den gerade erzeugten Button in eine Variable legt, erspart man sich den ständigen Zugriff auf das Array.
Das erkennen einer neuen Zeile geht auch einfacher.
Delphi-Quellcode:
var i, zeile, spalte: Integer;
    AbstandX, OffsetX: Integer;
    AbstandY, OffsetY: Integer;
    Btn: TButton;
begin

  SetLength(MyBtns, CONST_SOUNDBUTTONS);

  AbstandX := 10; // Abstand der einzelnen Spalten
  OffsetX := 25; // Abstand der ersten Spalte von links

  AbstandY := 20; // Abstand der einzelnen Zeilen
  OffsetY := 100; // Abstand der ersten Zeile von oben

  zeile := 0;
  spalte := 0;

  for i := 0 to CONST_SOUNDBUTTONS - 1 do
  begin
    Btn := TButton.Create(Self);
    MyBtns[I] := Btn;
    Btn.Parent := TabSheet2;
    Btn.Name := 'btnSound' + IntToStr(i);
    //Btn.Caption := 'Sound ' + IntToStr(i+1);

    // nur zum Ansehen der aktuellen Spalten- und Zeilenwerte
    Btn.Caption := IntToStr(spalte) + '|' +
                                        IntToStr(zeile);

    Btn.Height := 25;
    Btn.Width := 75;


    Btn.Left :=
      spalte * (AbstandX + Btn.Width) + OffsetX;

    Btn.Top :=
      zeile * (AbstandY + Btn.Height) + OffsetY;
    Inc(Spalte);

    if Spalte = 5  then
    begin
      Spalte:= 0;
      Inc(Zeile);
    end;
  end;
end;

Blitzschutz1 7. Apr 2022 20:38

AW: Anordnen von zur Laufzeit erzeugten Komponenten (hier Button)
 
Delphi-Quellcode:
 
    Inc(Spalte);

    if Spalte = 5 then
    begin
      Spalte:= 0;
      Inc(Zeile);
    end;
Genau!

Der Mensch ist ein komisches Wesen! Einmal auf dem falschen gedanklichen Weg und man kann stundenlang testen, denken und kommt doch nicht auf den rechten Pfad.

Danke!

Delphi.Narium 8. Apr 2022 08:31

AW: Anordnen von zur Laufzeit erzeugten Komponenten (hier Button)
 
Alternative:
Delphi-Quellcode:
 for i := 1 to CONST_SOUNDBUTTONS do

DeddyH 8. Apr 2022 10:05

AW: Anordnen von zur Laufzeit erzeugten Komponenten (hier Button)
 
Bessere Alternative:
Delphi-Quellcode:
for i := Low(MyBtns) to High(MyBtns) do

Delphi.Narium 8. Apr 2022 10:50

AW: Anordnen von zur Laufzeit erzeugten Komponenten (hier Button)
 
Wenn Low(MyBtns) gleich 0 ist, tritt das Problem aber wieder auf.

jziersch 8. Apr 2022 11:06

AW: Anordnen von zur Laufzeit erzeugten Komponenten (hier Button)
 
Aus Performance gründen Parent immer als letztes zuweisen, da das Fenster Handle dann erstellt wird.

Den Namen kann man leer lassen, die Zuweisung verursacht einen check auf Duplikate.
Wenn Du die buttons identifizieren willst, nimm lieber einen Tag.

Zitat:

Es werden 10 Button in einer schleife erzeugt, die in 5 Spalten und zwei Zeilen angeordnet werden sollen
Probier mal:
MyBtns[i].SetBounds(OffsetX + (i mod 5) * (75+XAbstand), OffsetY + (i div 5) * (25+YAbstand), 75, 25);

https://docwiki.embarcadero.com/Libr...trol.SetBounds

DeddyH 8. Apr 2022 11:28

AW: Anordnen von zur Laufzeit erzeugten Komponenten (hier Button)
 
Zitat:

Zitat von Delphi.Narium (Beitrag 1504439)
Wenn Low(MyBtns) gleich 0 ist, tritt das Problem aber wieder auf.

Bei dynamischen Arrays ist Low() immer 0. Nötigenfalls muss man Low() dann eben als Offset berücksichtigen. Ein dynamisches Array von 1 bis Length zu durchlaufen kann jedenfalls nicht die Lösung sein, es sei denn, man steht auf Fehlermeldungen.

Delphi.Narium 8. Apr 2022 11:32

AW: Anordnen von zur Laufzeit erzeugten Komponenten (hier Button)
 
Meine Version funktioniert natürlich nur, wenn das Array von 1 bis n geht.

Bei 'nem Array, dass bei 0 beginnt, ist sie natürlich kontraproduktiv bzw. unsinnig.


Alle Zeitangaben in WEZ +1. Es ist jetzt 09:47 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz