Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi Variable zur Laufzeit erstellen (https://www.delphipraxis.net/57384-variable-zur-laufzeit-erstellen.html)

Scorpion 20. Nov 2005 16:11


Variable zur Laufzeit erstellen
 
Hallo,

ich erstelle in meinem Programm meherere Images zur Laufzeit. Das klappt auch wunderbar. Nur weiss man vorher nicht, wieviele Images wirklich gebraucht werden.
Ich kann also keine Variablennamen in den Quellcode schreiben,weil ich nicht weiss wie viele... :(
Aber ohne einen im Quellcode definierten Variablennamen kann ich doch keine Komponente zur Laufzeit erstellen oder ?

Meine Frage also, was kann ich tun oder wie kann man Variablen zur Laufzeit definieren?

Gruß
Nico

leddl 20. Nov 2005 16:13

Re: Variable zur Laufzeit erstellen
 
Du könntest dir zB ein Array of TImage deklarieren.

Scorpion 20. Nov 2005 16:15

Re: Variable zur Laufzeit erstellen
 
Aber da habe ich doch auch eine vordefinierte Anzahl oder ?
Wie könnte das denn aussehen ?

turboPASCAL 20. Nov 2005 16:17

Re: Variable zur Laufzeit erstellen
 
Verwende ein Array zB.
Zitat:

var MyImages: Array of TImages
dann kannst du mit SetLength(MyImages, ...) die Anzahl der zu verwend. Images einstellen.

Der_Unwissende 20. Nov 2005 16:19

Re: Variable zur Laufzeit erstellen
 
Zitat:

Zitat von Scorpion
Nur weiss man vorher nicht, wieviele Images wirklich gebraucht werden.
Ich kann also keine Variablennamen in den Quellcode schreiben,weil ich nicht weiss wie viele... :(

Hi,
du kannst durchaus ein Image auch relativ annonym erstellen, aber das wäre wohl kaum das was du wirklich suchst. Am einfachsten ist es du schaust dir Datentypen an, deren Größe nicht zur Designzeit feststehen muss. Dazu gehören dynamische Arrays und Listen.
Ich persönlich würde dir zu Listen raten, da musst du dich weniger um die Anpassung der Größe ändern, dass übernimmt die Kapselung für dich. Schau einfach mal unter TObjectList in der Delphi Hilfe nach.

Ach als kleiner Tip vorweg, wenn du etwas aus der TObjectList holst, musst du es danach casten
Delphi-Quellcode:
var list : TObjectList
    image : TImage;
begin
  list := TObjectList.Create;
  list.Add(TImage.Create(nil));
  image := TImage(list.get(0));
  ....
  ....
end;
Grobes nicht überprüftes oder durchdachtes Beispiel, soll nur grob zeigen wie es geht, kann mich aber irren was die Syntax angeht. Jedenfalls kannst du es grob in der Richtung machen. Du solltest allerdings aufpassen, dass du die angelegten Images auch irgendwann wieder freigeben müsstest. Sonst müllst du dir ganz schnell deinen Speicher zu.

Gruß Der Unwissende

leddl 20. Nov 2005 16:24

Re: Variable zur Laufzeit erstellen
 
Zitat:

Zitat von Scorpion
Aber da habe ich doch auch eine vordefinierte Anzahl oder ?
Wie könnte das denn aussehen ?

Kommt drauf an, wie du es deklarierst.
Delphi-Quellcode:
myStaticImageArray : Array[1..x] of TImage;
wäre ein statisches Array, das immer x Elemente besitzt. Da kannst du an der Anzahl auch nichts mehr ändern.
Deklarierst du dein Array aber dynamisch
Delphi-Quellcode:
myDynamicImageArray : Array of TImage;
so kannst du zur Laufzeit jederzeit die Größe deines Arrays bestimmen.
Dazu mußt du beim Hinzufügen eines neuen Elementes immer die Länge des Arrays über
Delphi-Quellcode:
SetLength(myDynamicImageArray,newLength);
festlegen. (Wie turboPASCAL ja auch schon geschrieben hat).
Dabei solltest du beachten, daß dynamische Arrays 0-basiert sind - also das erste Element den Index 0 hat - und bis Length-1 laufen.

//Edit:
Und TObjectList ist natürlich auch eine gute Alternative

Scorpion 20. Nov 2005 16:29

Re: Variable zur Laufzeit erstellen
 
Hallo,

vielen Dank...

@leddl: Bei deiner Variante sagt er immer beim Eintragen in das Array... Unbekannte Variable.

@Der_Unwissende: Bei dir fragt sich der Quellcode was eine TObjectList sei?

Gruß Nico

ichbins 20. Nov 2005 16:31

Re: Variable zur Laufzeit erstellen
 
dynamische Arrays gehen erst ab D7...

dir wird nur eine Liste übrigbleiben. oder aber ein Update auf D7.

malo 20. Nov 2005 16:33

Re: Variable zur Laufzeit erstellen
 
Zitat:

Zitat von Scorpion
@leddl: Bei deiner Variante sagt er immer beim Eintragen in das Array... Unbekannte Variable.

Zeig doch mal bitte deinen Quelltext. Also die Zeile, wo der Fehler ist...

Zitat:

@Der_Unwissende: Bei dir fragt sich der Quellcode was eine TObjectList sei?
Wenn du in der OH nach Delphi-Referenz durchsuchenTObjectList schaust, wirst du feststellen, dass dir die Unit Contnrs fehlt. Die muss oben in der Uses-Klausel hinzugefügt werden.

leddl 20. Nov 2005 16:34

Re: Variable zur Laufzeit erstellen
 
Zitat:

Zitat von Scorpion
@leddl: Bei deiner Variante sagt er immer beim Eintragen in das Array... Unbekannte Variable.

Was für eine Variable? Auf die einzelnen Elemente des Arrays greifst du über
Delphi-Quellcode:
myDynamicImageArray[x]
zu. Oder meinst du "NewLength" bei meinem Aufruf von SetLength? Da mußt du natürlich die neue Länge des Array eintragen (Vorsicht, 0-basiert!)
Zitat:

Zitat von Scorpion
@Der_Unwissende: Bei dir fragt sich der Quellcode was eine TObjectList sei?

Schau doch einfach mal in die OH. Sehr wahrscheinlich mußt du dafür ne extra Unit einbinden.

Robert_G 20. Nov 2005 16:35

Re: Variable zur Laufzeit erstellen
 
Zitat:

Zitat von Scorpion
@Der_Unwissende: Bei dir fragt sich der Quellcode was eine TObjectList sei?

Klingt nach einem Fall für die Zaubertaste. (F1) :roll: Damit findest du auch die Unit, in der TObjectList deklariert ist... (Schreibe ich jetzt absichtlich nicht hierhin)

Array machen hier eigentlich absolut keinen Sinn.
Außer natürlich man hat keinen Bock sich Gedanken über die nettere Alternative zu machen. Dyn. Arrays sind wohl in 99% aller Fälle fehl am Platze. Auch wenn das vllt weitere 10 Jahre braucht um allg. erkannt zu werden... :wall:


Nachtrag:
Zitat:

Zitat von ichbins
dynamische Arrays gehen erst ab D7...
dir wird nur eine Liste übrigbleiben. oder aber ein Update auf D7.

Der war gut :lol: dyn Arrays gibt es seit D4...
Aber ein araybasierter Container (TList-Ableitung) oder eine richtige Liste dürften wohl fast immer praktischer sein.

malo 20. Nov 2005 16:39

Re: Variable zur Laufzeit erstellen
 
Zitat:

Zitat von Robert_G
Array machen hier eigentlich absolut keinen Sinn.

Hast du in der Schule nicht gelernt, was das ist? Das ist nämlich eine Behauptung. Und es muss dir niemand glauben, solange du diese Behauptung nicht bewiesen hast. Das habe ich sowohl im Deutschunterricht, als auch im Mathematikunterricht gelernt.

Scorpion 20. Nov 2005 16:40

Re: Variable zur Laufzeit erstellen
 
Hey...

Vielen Dank, jetzt klappt das mit der ObjectList :)

Gruß Nico

Robert_G 20. Nov 2005 16:42

Re: Variable zur Laufzeit erstellen
 
Zitat:

Zitat von malo
Zitat:

Zitat von Robert_G
Array machen hier eigentlich absolut keinen Sinn.

Hast du in der Schule nicht gelernt, was das ist? Das ist nämlich eine Behauptung. Und es muss dir niemand glauben, solange du diese Behauptung nicht bewiesen hast. Das habe ich sowohl im Deutschunterricht, als auch im Mathematikunterricht gelernt.

Mir muss niemand etwas glauben. Und ich werde jetzt nicht das Offensichtliche schreiben, nur weil so ein kleiner Nerd stolz die Definition einer Behauptung rezitiert hat... :lol:

ichbins 20. Nov 2005 16:51

Re: Variable zur Laufzeit erstellen
 
wieso sind dynamische Arrays denn sinnloser als Listen? Weil sie weniger Speicher verbrauchen? Weil sie auch mehrdimensional möglich sind? :gruebel:

Robert_G 20. Nov 2005 16:55

Re: Variable zur Laufzeit erstellen
 
Zitat:

Zitat von ichbins
wieso sind dynamische Arrays denn sinnloser als Listen? Weil sie weniger Speicher verbrauchen? Weil sie auch mehrdimensional möglich sind? :gruebel:

Weil ein Array nur ein primitiver Typ ist. Er kann von selbst rein gar nix, das heißt du darfst alles zu Fuss erledigen...
Eine ContainerKlasse hingegen sorgt automatisch für Wachstum und lässt dich Elemente tauschen, Einfügen, Anhangen oder Entfernen.
Aber ich merke schon, dass ich wieder Dinge schreibe, die eh niemanden interessieren...

malo 20. Nov 2005 16:59

Re: Variable zur Laufzeit erstellen
 
Zitat:

Zitat von Robert_G
Aber ich merke schon, dass ich wieder Dinge schreibe, die eh niemanden interessieren...

Du hast es verstanden :thumb:
:mrgreen:

Es geht nicht darum, dass es niemanden interessiert. Es geht darum, dass Listen gelegentlich nicht notwendig sind. Nur weil du für jeden Furz ein Objekt erzeugst, muss das ja nicht heißen, dass das automatisch besser ist als irgendetwas anderes.

Der_Unwissende 20. Nov 2005 17:06

Re: Variable zur Laufzeit erstellen
 
Zitat:

Zitat von ichbins
wieso sind dynamische Arrays denn sinnloser als Listen? Weil sie weniger Speicher verbrauchen? Weil sie auch mehrdimensional möglich sind? :gruebel:

Wo hast du nur diese lustigen Ideen her? Weniger Speicher? Wie kommst du denn darauf? All die Aufräumarbeiten, die eine TObjectlist leistet, stellt dir doch ein Array nicht automatisch zur Verfügung. Und (hier liegt das Problem) die wenigsten rufen ein finalize und setLength(array, 0) auf. Das wäre wirklich mal angebracht.
Zudem hat Delphi eine interessante Strategie was dyn. Arrays angeht, erhöh mal die Länge eines dyn. Arrays immer schön um 1 und du wirst merken dass das nicht dem Speicher entspricht, der alloziert wird. Dann wirst du auch schnell einsehen, dass sie alles andere als weniger Speicher verbrauchen.

Mehrdimensionale Arrays sind natürlich toll, aber was wäre gleich eine Liste von Listen?
Unabhängig davon kannst du die Daten auch linear anordnen und hast nichts anderes (ausser evtl. weniger Sprünge im Speicher, je nach Umsetzung). Jedenfalls wirst du häufiger mal auf mehrdimensional verzichten müssen und einfach rechnen und sehen ist mindestens genauso einfach, aber anderes Thema.

Drehen wir die Frage um, was genau kann ein dyn. Array mehr als eine Liste? Nun ja, da wir schon häufiger die Diskussion hatten kommen wir doch gleich dazu, TObjectList basiert auf dyn. Arrays, nimmt einem aber die Verwaltung ab. Das ist auch ganz gut, denn das ist eine der wichtigsten Ideen der Informatik (habe ich mal im Studium gelernt).
Du automatisierst hier eine Arbeit und validierst einmalig, dass sie immer funktioniert. Damit weißt du, dass du jedes mal eine funktionsfähige Verwaltung des Speichers durch deine TObjectList hast.
Verzichtest du aus irgendwelchen Gründen (z.B. ein paar Bytes mehr Speicher) auf dieses Funktionen, müsstest du jedes mal validieren, dass deine Lösung genauso der Spezifikation gerecht wird. Da wirst du dann merken, dass man doch schnell kleine Fehler macht oder was vergisst...
Und mal ehrlich, wie oft liest du die Zeile finalize wenn dyn. Arrays benutzt werden?

Gruß Der Unwissende

Der_Unwissende 20. Nov 2005 17:10

Re: Variable zur Laufzeit erstellen
 
Zitat:

Zitat von malo
Nur weil du für jeden Furz ein Objekt erzeugst, muss das ja nicht heißen, dass das automatisch besser ist als irgendetwas anderes.

Man, hätte man das früher gewusst, ich glaube man hätte die Objekt Orientierung nie erfunden :mrgreen:
Ist nur merkwürdig das man in Delphi Objekte eingeführt hat, man kam doch so schön ohne aus...
Ich meine die wertvollen microsek. die es kostet ein Objekt zu erzeugen, der riesige Speicheroverhead von ein paar Bytes pro Objekt und wofür? Nur weil die einem jede Menge sonst nicht vorhandener Einfachheit zur Verfügung stellen?!

Nieder mit der OOP!!!! Ehrlich!

ichbins 20. Nov 2005 17:32

Re: Variable zur Laufzeit erstellen
 
bei einer Liste muss ich aber auch list.free machen. setlength(array,0) ist da genauso aufwendig. Wenn du aber eine Mehrdimensionale Liste hast, summieren sich die paar Bytes und Mikrosekunden ziemlich schnell auf...

[ot]wieso ist robert_g gerade zum ehemaligen Benutzer mutiert? :gruebel:[/ot]

malo 20. Nov 2005 17:41

Re: Variable zur Laufzeit erstellen
 
Zitat:

Zitat von Der_Unwissende
Zitat:

Zitat von ichbins
wieso sind dynamische Arrays denn sinnloser als Listen? Weil sie weniger Speicher verbrauchen? Weil sie auch mehrdimensional möglich sind? :gruebel:

Wo hast du nur diese lustigen Ideen her? Weniger Speicher? Wie kommst du denn darauf? All die Aufräumarbeiten, die eine TObjectlist leistet, stellt dir doch ein Array nicht automatisch zur Verfügung. Und (hier liegt das Problem) die wenigsten rufen ein finalize und setLength(array, 0) auf

Aber du willst mir erzählen, dass jeder, der eine TObjectList erzeugt, sie auch wieder freigibt? :shock:


Zitat:

Zitat von Der_Unwissende
Zitat:

Zitat von malo
Nur weil du für jeden Furz ein Objekt erzeugst, muss das ja nicht heißen, dass das automatisch besser ist als irgendetwas anderes.

Man, hätte man das früher gewusst, ich glaube man hätte die Objekt Orientierung nie erfunden :mrgreen:
Ist nur merkwürdig das man in Delphi Objekte eingeführt hat, man kam doch so schön ohne aus...
Ich meine die wertvollen microsek. die es kostet ein Objekt zu erzeugen, der riesige Speicheroverhead von ein paar Bytes pro Objekt und wofür? Nur weil die einem jede Menge sonst nicht vorhandener Einfachheit zur Verfügung stellen?!

Nieder mit der OOP!!!! Ehrlich!

:gruebel:

Ich hab nicht gesagt, dass die OOP nicht ihre Vorzüge hat, geschweige denn dass sie schlecht ist :shock:

Ich meinte nur, dass es nicht immer notwendig ist, ein Objekt zu erzeugen. Manche Dinge sind anders viel leichter zu handhaben, wenn man kein Objekt erzeugt, bzw. bieten einem einfach keine besonderen Nachteile, die zwingend sind, ein Objekt zu erzeugen.
Für einfache Listen mit Variablen (dabei auch Komponentenerzeugung etc.) verwende ich i.d.R. auch Arrays. Wenn es darum geht, längere Listen zu erzeugen und zu verwalten, verwende ich Listen (TObjectList). Ich nehme immer das, was ich brauche.

Scorpion 20. Nov 2005 18:34

Re: Variable zur Laufzeit erstellen
 
Eine Frage hätte ich noch...

Wenn ich die Komponenten so wie Der_Unwissende erstelle, also per ObjectList klappt das wunderbar.
Doche welche Namen haben die Komponenten denn dann ?

Gruß,
Nico

leddl 20. Nov 2005 18:42

Re: Variable zur Laufzeit erstellen
 
Schau dir den Code doch mal genau an, da steht doch alles drin.
Delphi-Quellcode:
var list : TObjectList
    image : TImage;
begin
  list := TObjectList.Create;
  list.Add(TImage.Create(nil));
  image := TImage(list.get(0)); //<--
  ....
  ....
end;
An der markierten Stelle wird das 1. Element aus der Liste geholt und zu einem TImage gecastet.

Scorpion 20. Nov 2005 18:50

Re: Variable zur Laufzeit erstellen
 
:wall: *g* wie dumm, jetzt hab ichs...

Sagt mal, eine ObjectList kann man nicht 2 Spaltig machen ? :gruebel:

Bzw. mein Problem liegt auch darin, woher weiss ich denn, wenn ich eine Komponente ansprechen will, das wievielte Element es der Liste ist ?

Der_Unwissende 20. Nov 2005 19:10

Re: Variable zur Laufzeit erstellen
 
Zitat:

Zitat von Scorpion
:wall: *g* wie dumm, jetzt hab ichs...

Sagt mal, eine ObjectList kann man nicht 2 Spaltig machen ? :gruebel:

Bzw. mein Problem liegt auch darin, woher weiss ich denn, wenn ich eine Komponente ansprechen will, das wievielte Element es der Liste ist ?

Nun ja, du speicherst einfach nur die Referenz auf ein Objekt. Da musst du nichts zweispaltig machen (kann man natürlich auch). Du hast natürlich auch alle Eigenschaften der gespeicherten Objekte. D.h. du kannst auch folgendes tun:

Delphi-Quellcode:
var list : TObjectList;
    buffer : TImage;
    i : Integer;
begin
  list := TObjectList.Create;
  buffer := TImage.Create(nil);
  buffer.name := ...;
  list.add(buffer);
  ...
  ...
  if list.Count > 0 then
    begin
      for i := 0 to buffer.Count - 1 do
        begin
          if TImage(buffer.Items[i]).name = .... then
            begin
              // tu was du möchtest
              break;
            end;
        end;
    end;
end;
Mit dem Weg kannst du natürlich nach einer beliebigen Eigenschaft suchen (Name ist halt meistens eher unwichtig, wenn man erst zur Laufzeit erstellt).
Aber wenn es nur um den Namen geht, kannst du auch so nach dem Element suchen
Delphi-Quellcode:
var list : ComponentList;
    i : Integer;
begin
  ...
  ...
  if list.Count > 0 then
    begin
      for i := 0 to list.Count - 1 do
        begin
          if list.Items[i].name = .... then
            begin
              // mach was du willst
              break;
            end;
        end;
    end;
end;

Scorpion 20. Nov 2005 19:23

Re: Variable zur Laufzeit erstellen
 
Mein Problem, leider immernoch:

Ich habe jetzt mehrere TImages erstellt. Wenn ich jetzt ein bestimmes ansprechen will, sagen wir ich klicke drauf. Woher weiss ich dann den Komponentennamen ??

Khabarakh 20. Nov 2005 19:48

Re: Variable zur Laufzeit erstellen
 
Mit dem Parameter Sender bekommst du doch das aktuelle Image. Den Index des Images kannst du dann über TObjectList.IndexOf ermitteln

Scorpion 20. Nov 2005 20:33

Re: Variable zur Laufzeit erstellen
 
Stimmt, thx


Alle Zeitangaben in WEZ +1. Es ist jetzt 17:57 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 by Thomas Breitkreuz