Entwickler-Ecke

Grafische Benutzeroberflächen (VCL & FireMonkey) - Felder im Programmlauf erstellen


Jakane - Di 21.06.11 09:34
Titel: Felder im Programmlauf erstellen
Hallo liebe Delphi-Helfer :)

ich habe ein Formular und möchte, wenn der Anwender in ein Feld was reingeschrieben hat, dass dann automatisch ein neues Textfeld erstellt wird, ohne das ich das vorher im Programm vorgebe.

Daher die Frage:
Wie sage ich Delphi, erstelle mir ein EditFeld
Namens Feld_x (x als berechnende Variable)

auf Top:= Höhe * x und Width:= 5


Sprich, Name mit Variablen Wert zuweisen oder mit festen Wert und natürlich das das Feld dann auch wirklich da ist für den Anwender :)

Danke an alle die helfen können :)


Moderiert von user profile iconNarses: Topic aus Dateizugriff verschoben am Di 21.06.2011 um 12:12


pwsolaris - Di 21.06.11 10:01

Hi,

du möchtest also ein normales Edit-Feld zur Laufzeit hinzufügen?
Ich habe das bisher nur mit Bildern (TImage) gemacht, denke aber, dass das Prinzip wohl das gleiche ist ;)

Zunächst einmal habe ich eine Variable der benötigten Komponente erstellt:

Delphi-Quelltext
1:
2:
var
  test : TEdit;


Dann habe ich mir eine kleine Prozedur geschrieben, in der ich meine Komponente erstelle:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
begin
  Test := TEdit.create(self);
  Test.parent  := self;
  Test.height  := 10;
  Test.width   := 100;
  Test.top     := 100;
  Test.left    := 100;
  Test.visible := true;
  Test.Show;
  Test.enabled := true;
end;


Mag sein, dass die ganze Geschichte einfacher zu lösen ist oder sauberer umzusetzen ist, aber das ist immerhin ein Anfang ;)


thepaine91 - Di 21.06.11 10:05

Unter umständen ist es auch einfacher das Feld einfach nur auf Hidden zu setzen im Objektinspektor und bei bedarf auf visible....


Jakane - Di 21.06.11 12:02

user profile iconthepaine91 hat folgendes geschrieben Zum zitierten Posting springen:
Unter umständen ist es auch einfacher das Feld einfach nur auf Hidden zu setzen im Objektinspektor und bei bedarf auf visible....


wer lernen will darf nicht immer das gleiche benutzen

ausserdem weiss ich ja nicht ob er 1, 5 oder 20 felder braucht ^^ oder mehr deswegen soll sich das berechnen

---Moderiert von user profile iconNarses: Beiträge zusammengefasst---

user profile iconpwsolaris hat folgendes geschrieben Zum zitierten Posting springen:
Zunächst einmal habe ich eine Variable der benötigten Komponente erstellt:

Delphi-Quelltext
1:
2:
var
  test : TEdit;

Dann habe ich mir eine kleine Prozedur geschrieben, in der ich meine Komponente erstelle:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
begin
  Test := TEdit.create(self);
  Test.parent  := self;
  Test.height  := 10;
  Test.width   := 100;
  Test.top     := 100;
  Test.left    := 100;
  Test.visible := true;
  Test.Show;
  Test.enabled := true;
end;

Mag sein, dass die ganze Geschichte einfacher zu lösen ist oder sauberer umzusetzen ist, aber das ist immerhin ein Anfang ;)

es funktioniert, den rest krieg ich wieder alleine raus, danke :D


thepaine91 - Di 21.06.11 12:16

Ah hatte das falsch gelesen in deinem Fall ist es so natürlich sinnvoller....


Kay E. - Di 21.06.11 13:42

Wobei anzumerken ist, dass du das Objekt dynamisch erstellst. Du reservierst dir damit Speicherplatz, den du dann auch manuell wieder freigeben musst wenn dus nicht mehr brauchst, in deinem Fall mit Test.Free;
Desweiteren brauchst du die drei Zeilen hier nicht:

Delphi-Quelltext
1:
2:
3:
4:
5:
begin
  Test.visible := true;
  Test.Show;
  Test.enabled := true;
end;


Das sind die Standarteinstellungen der Komponente, so dass du sie nicht extra noch einmal setzen musst.
Wichtig ist, dass du als Parent die Form angibst, auf der das Edit-Feld angezeigt werden soll. Also

Delphi-Quelltext
1:
Test.Parent := Form1;                    

Das hat den Vorteil, dass, wenn du vergisst, die Komponente freizugeben, der GarbageCollector den Speicher freigeben kann und auch weitere Sachen sind damit sinnvoller.

Grüße Kay


thepaine91 - Di 21.06.11 14:05

Kann dir nicht ganz zustimmen 1. gehe ich davon aus das Self in dem Fall Form1 ist.
Und 2.

The AOwner parameter is the owner of the T(Custom)Form object. The owner of the form is responsible for freeing the form (memory allocated by the form) when needed. What's more the form created appears in the Components array of its owner. Second, the form is destroyed automatically when its owner is destroyed. For forms, the latter is usually more important.
Should you provide "nil", "self" or "Application"?

Alternativ: http://delphi.about.com/od/adptips2005/qt/nilselfapp.htm

Edit:
Self ist meiner Meinung nach sowieso besser da er dann unabhängig vom Namen seines Formulars ist. Er kann es also beliebig umbenennen ohne überall Form1 z.b. in Form2 zu ändern.

//EDIT: zu schnell... :mrgreen:


Narses - Di 21.06.11 14:07

Moin!

user profile iconKay E. hat folgendes geschrieben Zum zitierten Posting springen:
Wobei anzumerken ist, dass du das Objekt dynamisch erstellst. Du reservierst dir damit Speicherplatz, den du dann auch manuell wieder freigeben musst wenn dus nicht mehr brauchst, in deinem Fall mit Test.Free;
Ich nehme mal an, du beziehst dich auf folgendes Stück Code:
user profile iconpwsolaris hat folgendes geschrieben Zum zitierten Posting springen:

Delphi-Quelltext
1:
2:
3:
4:
  Test := TEdit.create(self);
  Test.parent  := self;
  Test.height  := 10;
  //...
Wenn dem so ist, dann ist deine Aussage leider falsch, denn durch die Angabe eines Owners wird die neue Komponente Eigentum des Formulars (hier: self) und damit beim Beenden des Programmes automatisch freigegeben. Es ist eher so, dass du solche Komponenten (also mit beim Erzeugen angegebenem Owner) besser nicht manuell wieder freigibst! :shock: Wenn du die Komponenten selbst verwalten willst, solltest du als Owner NIL beim Create übergeben. :idea:

user profile iconKay E. hat folgendes geschrieben Zum zitierten Posting springen:
Wichtig ist, dass du als Parent die Form angibst, auf der das Edit-Feld angezeigt werden soll. Also

Delphi-Quelltext
1:
Test.Parent := Form1;                    
Das ist in dem Code oben doch drin, sogar allgemeiner (=besser) per self formuliert. ;)

user profile iconKay E. hat folgendes geschrieben Zum zitierten Posting springen:
Das hat den Vorteil, dass, wenn du vergisst, die Komponente freizugeben, der GarbageCollector den Speicher freigeben kann und auch weitere Sachen sind damit sinnvoller.
Ein seltsames Gerücht: Delphi hat keinen GarbageCollector :!: Speicher, den du anforderst und nicht wieder frei gibst, ist bis zum Programmende unwiederbringlich verloren. :lupe: :? Z.B. C# oder Java arbeiten mit einem GarbageCollector, der nicht mehr referenzierten Speicher einsammelt und wieder zur Verfügung stellt.

cu
Narses

//EDIT: zu langsam... :roll:


Jakane - Mi 22.06.11 07:36

hmm...
In einem steht irgendwas englisches und ich glaube ein Mod hat das korrigiert, ist daswas da steht irgendwie relevant für mein Fall....?

Bis auf

user profile iconKay E. hat folgendes geschrieben Zum zitierten Posting springen:
Wichtig ist, dass du als Parent die Form angibst, auf der das Edit-Feld angezeigt werden soll. Also

Delphi-Quelltext
1:
Test.Parent := Form1;                    


Versteh nämlich nix :D
Aber der Hinweis ist Prima, da ich nämlich mit InfoPanel arbeite :D


thepaine91 - Mi 22.06.11 08:05

Englisch sollte man verstehen als Programmierer. ;)

Aber Narses hat es auch wunderbar auf Deutsch formuliert.


Jakane - Mi 22.06.11 10:02

versteh trotzdem nicht was er meint :D


Narses - Mi 22.06.11 10:15

Moin!

user profile iconJakane hat folgendes geschrieben Zum zitierten Posting springen:
versteh trotzdem nicht was er meint :D
Was genau verstehst du nicht? :lupe:

cu
Narses


Jakane - Mi 22.06.11 10:36

user profile iconNarses hat folgendes geschrieben Zum zitierten Posting springen:
Es ist eher so, dass du solche Komponenten (also mit beim Erzeugen angegebenem Owner) besser nicht manuell wieder freigibst! :shock: Wenn du die Komponenten selbst verwalten willst, solltest du als Owner NIL beim Create übergeben. :idea:

user profile iconKay E. hat folgendes geschrieben Zum zitierten Posting springen:
Das hat den Vorteil, dass, wenn du vergisst, die Komponente freizugeben, der GarbageCollector den Speicher freigeben kann und auch weitere Sachen sind damit sinnvoller.
Ein seltsames Gerücht: Delphi hat keinen GarbageCollector :!: Speicher, den du anforderst und nicht wieder frei gibst, ist bis zum Programmende unwiederbringlich verloren. :lupe: :? Z.B. C# oder Java arbeiten mit einem GarbageCollector, der nicht mehr referenzierten Speicher einsammelt und wieder zur Verfügung stellt.

damit kann ich so gar nichts anfangen, aber ich habe auch nicht das gefühl das es für mich wichtig ist.

ich habe nur grade gemerkt, felder auslesen die erst bei programmlauf erzeugt werden krieg ich irgendwie nicht hin :?:

wie kann ich so ein feld auslesen, zB in eine variable? :)

Moderiert von user profile iconNarses: Zitat repariert.

---Moderiert von user profile iconNarses: Beiträge zusammengefasst---


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
var
  txtNeu : TEdit;
Begin
  txtNeu:= TEdit.Create(Self);
  txtNeu.Parent:= fmAuftrag.IPAuftragPos;
  txtNeu.Height:= 21;
  txtNeu.Width:= 25;
  txtNeu.Top:= gPos * 25;
  txtNeu.Left:= 10;
  txtNeu.MaxLength:= 3;
  txtNeu.Name:= 'txtPos_' + IntToStr(gPos);
  txtNeu.OnKeyPress:= txtPos_0KeyPress;
  if gPos < 10 then txtNeu.Text:= '00' + IntToStr(gPos) else
    if gPos < 100 then txtNeu.Text:= '0' + IntToStr(gPos) else
      txtNeu.Text:= IntToStr(gPos);


also so schaut das bei mir aus :mrgreen:

Moderiert von user profile iconNarses: Code- durch Delphi-Tags ersetzt


Narses - Mi 22.06.11 10:50

Moin!

user profile iconJakane hat folgendes geschrieben Zum zitierten Posting springen:
damit kann ich so gar nichts anfangen, aber ich habe auch nicht das gefühl das es für mich wichtig ist.
OK, ich mach nochmal eine Kurzfassung für dich:

user profile iconNarses hat folgendes geschrieben Zum zitierten Posting springen:
Es ist eher so, dass du solche Komponenten (also mit beim Erzeugen angegebenem Owner) besser nicht manuell wieder freigibst! :shock: Wenn du die Komponenten selbst verwalten willst, solltest du als Owner NIL beim Create übergeben. :idea:
Fazit: Lass das txtNeu.Free; weg, da du hier txtNeu:= TEdit.Create(Self); stehen hast. :idea:

user profile iconNarses hat folgendes geschrieben Zum zitierten Posting springen:
user profile iconKay E. hat folgendes geschrieben Zum zitierten Posting springen:
Das hat den Vorteil, dass, wenn du vergisst, die Komponente freizugeben, der GarbageCollector den Speicher freigeben kann und auch weitere Sachen sind damit sinnvoller.
Ein seltsames Gerücht: Delphi hat keinen GarbageCollector :!: Speicher, den du anforderst und nicht wieder frei gibst, ist bis zum Programmende unwiederbringlich verloren. :lupe: :? Z.B. C# oder Java arbeiten mit einem GarbageCollector, der nicht mehr referenzierten Speicher einsammelt und wieder zur Verfügung stellt.
Das ist nur Hintergrund und eigentlich an user profile iconKay E. gerichtet gewesen. :idea: Fazit: Heute für dich nicht wichtig. ;)


user profile iconJakane hat folgendes geschrieben Zum zitierten Posting springen:
wie kann ich so ein feld auslesen, zB in eine variable?
Das Problem ist etwas komplexer, als es auf den ersten Blick aussieht: Du hast die Variable txtNeu: TEdit lokal deklariert, deshalb hast du nach dem Ende der Prozedur keinen Zugriff mehr darauf. :idea: Einfach (aber unschöne Lösung): Global deklarieren (zumindest zum Testen kannste das mal machen). Wenn du das später mit viel mehr Komponenten machen willst, solltest du dir die Referenzen dazu in einer z.B. TObjectList aufheben.

cu
Narses


Jakane - Mi 22.06.11 10:59

user profile iconNarses hat folgendes geschrieben Zum zitierten Posting springen:
user profile iconJakane hat folgendes geschrieben Zum zitierten Posting springen:
wie kann ich so ein feld auslesen, zB in eine variable?
Das Problem ist etwas komplexer, als es auf den ersten Blick aussieht: Du hast die Variable txtNeu: TEdit lokal deklariert, deshalb hast du nach dem Ende der Prozedur keinen Zugriff mehr darauf. :idea: Einfach (aber unschöne Lösung): Global deklarieren (zumindest zum Testen kannste das mal machen). Wenn du das später mit viel mehr Komponenten machen willst, solltest du dir die Referenzen dazu in einer z.B. TObjectList aufheben.

1. danke fürs zusammenfassen
2. danke das du meine posts repariert hast und
3....

ich habe 6 felder pro durchgang die ich auf die weise erstelle, wie mach ich das mit der obejektliste?

Moderiert von user profile iconNarses: Zitat gekürzt.


thepaine91 - Mi 22.06.11 11:36

http://www.delphi-treff.de/tutorials/vcl/tobjectlist/grundlagen/


Jakane - Mi 22.06.11 12:13

ich merk wiedermal... mit komponenten die ich nicht sehen kann lern ich den umgang nur schwer :cry:

erstellen, hinzufügen und löschen ist klar

aber wie verwend ich das sinnvoll mit meinem problem :(


thepaine91 - Mi 22.06.11 16:00

Da wo du Felder erzeugst fügst du sie in der Liste hinzu da wo du Felder verwerfen möchtest Löscht du sie aus der Liste ich verstehe grade nicht was daran für dich genau Unklar ist?

Erstell doch zuerst eine Methode zum erstellen der Felder und wenn du dann Probleme hast kannst du eine spezifische Frage inkl. Codebeispiel stellen. Aber ich finde du solltest dir selbst die Gedanken machen wie du das sinnvoll kombinierst.