![]() |
dynamische Komponenten
Wie kann ich ein Form dazubringen,
mir Label zur erstellen in der Anzahl die ich möchte, aber so anordnet das es "ein Bild" gibt.D.h. wenn es zb: 12 sind 4x3 Spalten/Zeilen, wenn es 24 sind 4x6 ? Hab sowas schon in PHP gemacht, aber hier keinen Plan :( PS: Die Übergabe der Anzahl ist durch eine globale VAriable geregelt. |
Delphi-Quellcode:
for i := 0 to Anzahl - 1 do
begin Spalte := i mod 4; Zeile := i div 4; ErzeugeLabel({Left:}Spalte * 80, {Top:}Zeile * 25); end; |
kannst du mir bitte das erklären?
Nur das ich weiss was da passiert. |
Stelle dir vor du legtst mehrere Steine auf ein Brett. Den Ersten legst du ganz links oben hin, den Zweiten rechts daneben, den Dritten wiederum daneben und den Vierten ebenfalls. Den Fünften hingegen legst du unter den Ersten, ...
Um nun herauszubekommen, in welcher Zeile du den Stein hinlegen musst, ziehst du 1 von der Nummer ab (also Stein 1 ist Stein 0) und dividierst diesen Wert durch 4. Somit ergibt sich für die Steine mit Index 0-3 die Zeile mit Index 0 (0 div 4 = 0, 1 div 4 = 0, ... 3 div 4 = 0). Der Stein mit Index 4 nun ist durch 4 Teilbar und ergibt somit die Zeile mit Index 1. ... Um nun aber noch die richtige Spalte herauszubekommen benötigen wir den Restwert der Division (mod). So ergibt 0 mod 4=0, 1 mod 4=1, 2 mod 4=2, 3 mod 4=3. Und für den Stein mit dem Index 4 ergibt dann 4 mod 4=0, womit die Spaltenzählung von vorne beginnt. |
Danke für die Ausführung.
Ich habe folgenden Test gemacht:
Code:
es startet auch,keine Fehlermeldung, aber es werden keine Labels,gezeichnet.
procedure TForm1.FormShow(Sender: TObject);
var i,Spalte,Zeile:integer; aLabel: TLabel; begin for i := 0 to 24 - 1 do begin Spalte := i mod 4; Zeile := i div 4; aLabel:=TLabel.Create(Self); aLabel.Left:=Spalte*80; aLabel.Top:=Zeile*25; aLabel.Caption:='Label'+IntToStr(i); end; end; was ist falsch? |
wenn mich nicht alles täuscht ist der kram standardmäßig auf invisible gestellt...
|
bei create?
denn normalerweise eher nicht. |
witzig! das Form heisst wie das letzte Label:Nämlich Label23.
Und wenn ich noch Height und Width übergebe ist das Form in diese Grösse. dabei sage ich doch das aLabel ein TLabel ist...... |
Ich reiche dir mal ein
Delphi-Quellcode:
aLabel.Parent := Self;
|
kaum zu glauben..in der Tat jetzt gehts.
Also muss ich den Labels sagen zu wem sie gehören?! Danke |
Ja, du musst jeder Komponente sagen, wer für das Freigeben zuständig ist (Owner) und wer für das Anzeigen (Parent).
|
Ich hab noch einen :mrgreen:
wie sage ich dem ersten LAbel an welche Position es muss. Denn es wird ganz links oben mit dem Aufbau der Labels begonnen. Bisher konnt ich immer alles auf IDE positionieren.Aber mit Komps die erst zur Laufzeit erstellt hantiere ich zum erstenmal. Einen schönen Montag |
Verschieben kannst du das ganze, indem du bei der Zuweisung an Left unt Top noch einen (konstanten) Wert hinzufügst:
Delphi-Quellcode:
aLabel.Left := StartX + Spalte*80;
aLabel.Top := StartY + Zeile*25; |
Moin Zusammen,
Zitat:
Bei dynamisch erzeugten TTabSheet, muss man auch noch das zugehörige PageControl angeben, damit man von den Tabsheets was sieht. |
Habt vielen Dank,
jetzt klappt es so wie ich es wollte.Und verstanden hab ich es auch :angle2: , hoffe ich jedenfalls. Wie spricht man im laufenden Programm so eine erstellte Komponente an? Wie eine "normale" auch?Denn sie sollen ja im Programm auch weiterbehandelt, bzw angesprochen werden. Ich glaub das war jetzt ne blöde Frage,egal :o) |
Entweder du legst ein Array[0..24-1] of TLabel an, oder du verpasst jedem Label auch einen Namen, den du dann mit Owner.FindComponent wieder finden kannst.
|
Moin Privateer,
Du hast doch in dem einen Beispiel eine Variable aLabel vom Typ TLabel. aLabel muss nur an einer Stelle im Programm deklariert werden, so dass Du von jeder Stelle an der Du sie brauchst auch da rankommst. Wird sie z.B. nur innerhalb von Methode von Form1 gebraucht, kannst Du dort im Abschnitt private die Variable unterbringen.
Delphi-Quellcode:
Das führende F muss nicht sein, damit wird nur den Namenskonventionen für Felder (Variablen) von Objekten/Klassen genüge getan.
TForm1 = class(TForm)
... private FaLabel : TLabel; ... end; var Form1 : TForm1; |
Das Problem dabei ist aber, dass die Variable aLabel eben nicht alle 24 Labels gleichzeitig referenzieren kann. Somit wird er um ein Array bzw. die Name-Lösung nicht herumkommen.
|
wie soll das funktionieren mit dem array?
Die Anzahl der Labels ist ja variabel. *schnüff* |
Schon mal was von einem dynamischen Array gehört?
Delphi-Quellcode:
SetLength(LabelArray, AnzahlDerLabels);
|
nein :oops:
|
probier mal das zu verstehen, und eventuell anzupassen:
Delphi-Quellcode:
unit Unit1;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) Button1: TButton; procedure Button1Click(Sender: TObject); procedure LabelClick(Sender: Tobject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; DeineLabel: array of TLabel; implementation {$R *.dfm} procedure TForm1.Button1Click(Sender: TObject); var i : Integer; begin i := succ(High(DeineLabel)); SetLength(DeineLabel,i + 1); //Der array mit deinen Labeln wird eins länger DeineLabel[i] := TLabel.Create(Form1); //In den grade erschaffenen Platz kommt ein Label DeineLabel[i].Left := 10; //Wohin DeineLabel[i].Top := i * 20; //Wohin DeineLabel[i].Color := clred; //Farbe DeineLabel[i].OnClick := LabelClick; //Was ist, wenn man klickt insertcontrol(DeineLabel[i]); //Label "wirklich" erstellen end; procedure TForm1.LabelClick(Sender: TObject); begin if Sender = DeineLabel[0] {irgendeine Zahl statt 0} then {was bei dem Label passieren soll} Form1.Close; end; end. |
Und noch eine kurze Erklärung zu
Zitat:
Delphi-Quellcode:
DeineLabel[i].Parent := Self;
|
@Nailor
in deinem Beispiel,ich blick offengesagt noch nicht ganz durch. Wieviele Labels werden in diesem Beispiel denn erstellt.Das kann ich darin nicht sehen.Oder ist dein arraynur angedeudet? |
Bei Nailors Beispiel werden so viele Labels erzeugt wie du auf den Button Button1 klickst.
|
jbg meint, dass jedesMal, wenn man auf den Button klickt, ein neues Label entsteht. Du kannst auch den Code 1:1 ausschneiden, bei Delphi ein neues Projekt starten, einen einzigen Button einfügen und das Programm starten. Dann kannst du sehen, was es macht.
Dann kannst du ein paar Werte ändern, und per Trial and Error dir ein paar Auswirkungen klar machen. |
gehts das nicht einfacher?
Jedem Label einfach einen Namen verpassen wie einen Startwert festlegen dann jeweils um 1 hochzählen? |
Moin Privateer,
wenn Du den Labeln beim Erzeugen keinen Namen zuweist, wird der Standardname erzeugt, also eben Label1, Label2 usw., nur lassen sie sich über ein Array of TLabel leichter ansprechen. Sonst müsstest Du sie immer mit FindComponent suchen. |
Hi Chris,
das werden sie sowieso in jedem Fall.Jedenfalls in diesem Programm. Beispiel:
Code:
So und so ähnlich werden sie im kompletten Programm angesprochen.Deswegen meine Vermutung ob es nicht einfacher ginge.
procedure TForm1.AnyInChange(Sender: TObject);
var bEdit: TEdit; cLabel: TLabel; begin if Sender <> nil then if Sender is TEdit then begin bEdit := FindComponent('in' + Copy(TEdit(Sender).Name, 3, 2)) as TEdit; cLabel := Form2.FindComponent('out' + Copy(TEdit(Sender).Name,3,2)) as TLabel; cLabel.Caption:=bEdit.Text; end; end; Ich konnte es nur nicht nachvollziehen, ob jedes Label den richtigen Namen bekommt, weil es man nicht sieht. Denn alles "Findcomponents" sind auf eine bestimmte Zahl abgestimmt.Will sagen egal wie die Komponenten heissen haben sie die gleich Zahl, die die ich ansprechen will. Einen geruhsamen heiligen Abend an alle! (Werd noch a bisserl rumprobieren :o) ) |
Moin Privateer,
nimm doch lieber die Array Variante. Das dürfe deutlich einfacher gehen. |
nun stehen aber schon alle proceduren auf findcomponents.dann muss ich ja alles wieder umschmeissen.
Wenn ich das richtig verstanden haben, kann ich trotzdem so erzeugen:
Code:
und mit findcomponents ansprechen?!
var
i,Spalte,Zeile:integer; aLabel: TLabel; begin for i := 0 to 25 - 1 do begin Spalte := i mod 4; Zeile := i div 4; aLabel.Parent:=Self; aLabel:=TLabel.Create(Self); aLabel.Left:=50+Spalte*80; aLabel.Top:=50+Zeile*25; aLabel.Caption:='Label'+IntToStr(i); end; end; |
Moin Privateer,
ja, das sollte gehen. |
ich habe boch einen Christian.. :mrgreen:
Ist es prinzipell möglich solchen Komps zu sagen wie gross sie sein sollen? Ich meine wenn das Array bis 24 geht, sollen die Labels kleiner sein, als wenn nur 12 angezeigt werden. (Gleich ist es soweit...und ich fliege aus'm Board) |
sorry, falls das falsch ankam mit dem rausfliegen..
war etwas ironisches zu mir selbst |
Moin Privateer,
wenn Du die Eigenschaft AutoSize der Label auf false setzt, kannst Du problemlos die Eigenschaften Width und Height verwenden, um die Grösse Deinen Wünschen anzupassen. (falls es das war, was Du wissen wolltest;-)) |
So weit, so gut.Bleibt für mich die Frage wie sag ich's ihnen, den Labels.
Code:
oder so ähnlich?
if Anzahl >=12 then
begin aLabel.Width:=100; aLabel.Height:=60; end else .... Geht das nich auch unter Prozentualen Angaben?? ?Ist es eigentlich möglich Komponenten eine gewisse Transparenz zu geben? |
Alle Zeitangaben in WEZ +1. Es ist jetzt 18:45 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