Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi TObjektList mit 2 oder mehr TObjekte (https://www.delphipraxis.net/199155-tobjektlist-mit-2-oder-mehr-tobjekte.html)

alfold 30. Dez 2018 19:56

Delphi-Version: 7

TObjektList mit 2 oder mehr TObjekte
 
Hi, alle miteinander

Kurze Erklärung,

Ich erstelle 2 Objekte, die ich in einer Objektliste verwalten möchte.
Meine Frage:
Wie erkenne ich, wie viele der einzelnen Objekte vorhanden sind?
Es gibt ja leider kein getrenntes Add.
Ich kann zwar anhand der Items feststellen wo und wie viele es gibt und sie dann als einzelne Counts zuordnen.
z.B. CountRow, CountCol

Ist aber nicht sehr nützlich da das ganze ja Dynamisch erzeugt wird und ich auf die Items zugreifen muss.
Gibt es eine Möglichkeit das "add" zu trennen??
Das ganze muss auch noch gespeichert und gelesen werden!

Delphi-Quellcode:
type
  TSoundRow = class(TObject)
     Soundfile: ShortString;
      SoundName: ShortString;
      SoundColor: TColor;
      CommentText: ShortString;
      CommentColor: TColor;
      CommentSize: Integer;
      SzeneText: ShortString;
      SzeneColor: TColor;
      ColIndex: Integer;
      Start: TTime;
      Anfang: TTime;
      Ende: TTime;
      LoopA: TTime;
      LoopE: TTime;
      VolA: Integer;
      VolE: Integer;
      FadeTime: real;

      FadeIn: Boolean;
      FadeOut: Boolean;
      FwStop: Boolean;
  end;

  TSoundCol = class(TObject)
       ColName: ShortString;
       ColColor: TColor;
       ColWidth: Integer;
  end;

    TAudioList = class(TObjectList)
      MasterName: ShortString;
      MasterColWidth: Integer;
      MasterColor: TColor;
      CommentName: ShortString;
      CommentColWidth: Integer;
      CommentNameColor: TColor;

      protected
        procedure SetRow(i: Integer; aSoundRow: TSoundRow);
        procedure SetCol(i: Integer; aSoundCol: TSoundCol);
        function GetRow(i: Integer): TSoundRow;
        function GetCol(i: Integer): TSoundCol;
        function getRowCount: Integer;
        function getColCount: Integer;
      public
        property SounRow[i: Integer]: TSoundRow read GetRow write SetRow;
        property SoundCol[i: Integer]: TSoundCol read GetCol write SetCol;
        property CountRow: Integer read getRowCount;
        property CountCol: Integer read getColCount;
     //   function addSoundRow(Aobjekt: TSoundRow): Integer;
     //   function addSoundCol(Aobjekt: TSoundCol): Integer;

     //   procedure SaveToFile(const Fname: string);
     //   procedure LoadFromFile(const Fname: string);

  end;
Ich bin erst am Anfang von dem ganzen "ObjectList" usw.
Vieles gelesen die hälfte nur verstanden, also fängt man mal an:wink:
Ich hoffe ihr könnt mir helfen.

Gruß alfold

Dalai 30. Dez 2018 20:19

AW: TObjektList mit 2 oder mehr TObjekte
 
Delphi-Referenz durchsuchenTObjectList.Count?

Der Sinn hinter getrennten Counts ergibt sich mir nicht. Aber das musst du selber wissen (oder erfragen).

Grüße
Dalai

alfold 30. Dez 2018 20:33

AW: TObjektList mit 2 oder mehr TObjekte
 
Zitat:

Zitat von Dalai (Beitrag 1422335)
Delphi-Referenz durchsuchenTObjectList.Count?

Der Sinn hinter getrennten Counts ergibt sich mir nicht. .....
Grüße
Dalai

Im Prinzip schon, wenn man auf die einzelnen unterschiedlichen Objecte über das Item zu greifen muss. Z.B colcount ist die Anzahl Spalten und das item 1 wöhre die spalte 1. geht aber in diesem fall nicht!:cry:

gruß alfold

jaenicke 30. Dez 2018 21:08

AW: TObjektList mit 2 oder mehr TObjekte
 
Es macht keinen Sinn dann nur eine Liste zu benutzen. Wie wäre es, wenn du einfach zwei Listen innerhalb deiner Klasse nutzt statt von einer TObjectList abzuleiten?

Und wenn du z.B. die kostenlose aktuelle Community Edition benutzen könntest, könntest du auch eine TObjectList<TSoundCol> und eine TObjectList<TSoundRow> benutzen ohne zu casten.

p80286 30. Dez 2018 21:30

AW: TObjektList mit 2 oder mehr TObjekte
 
Zitat:

Zitat von alfold (Beitrag 1422336)

Im Prinzip schon, wenn man auf die einzelnen unterschiedlichen Objecte über das Item zu greifen muss. Z.B colcount ist die Anzahl Spalten und das item 1 wöhre die spalte 1. geht aber in diesem fall nicht!:cry:

gruß alfold

Klngt wie rektale Augenoperation.
Wenn Du unterschiedliche Objekte in einer Liste verwalten willst, kannst Du sie nur dort gleich behandeln wo sie auch gleich sind.

Gruß
K-H

alfold 30. Dez 2018 21:47

AW: TObjektList mit 2 oder mehr TObjekte
 
Zitat:

Zitat von p80286 (Beitrag 1422340)
....
Wenn Du unterschiedliche Objekte in einer Liste verwalten willst, kannst Du sie nur dort gleich behandeln wo sie auch gleich sind.

Gruß
K-H

Hab ich ja schon mitbekommen zu mindestens was das Item der Objektliste betrifft.
Hätt ja sein können das man da dran drehen kann!?
In etwa so
Delphi-Quellcode:
function addSoundRow(Aobjekt: TSoundRow): Integer;
function addSoundCol(Aobjekt: TSoundCol): Integer;
Zitat:

Zitat von jaenicke (Beitrag 1422337)
Es macht keinen Sinn dann nur eine Liste zu benutzen. Wie wäre es, wenn du einfach zwei Listen innerhalb deiner Klasse nutzt statt von einer TObjectList abzuleiten?

Und wenn du z.B. die kostenlose aktuelle Community Edition benutzen könntest, könntest du auch eine TObjectList<TSoundCol> und eine TObjectList<TSoundRow> benutzen ohne zu casten.

Ja, werde ich wohl nicht drum rum kommen. War ja auch nur so eine Idee.

Wird hoffentlich kein Problem dann beim Speichern ???.

Gruß alfold

scrat1979 31. Dez 2018 00:12

AW: TObjektList mit 2 oder mehr TObjekte
 
Zum erkennen wieviele Objekte vom jeweiligen Typ vorhanden sind könntest du folgendes machen (Code inkomplett aber die Vorgehensweise sollte klar sein):

Delphi-Quellcode:
for i:=0 to Count-1 do
 If Items[i] is TSoundRow then...

hoika 31. Dez 2018 04:43

AW: TObjektList mit 2 oder mehr TObjekte
 
Hallo,
warum soll es ein Speicher-Problem geben?
Du schreibst den Speichern-Code ja auch, oder?

alfold 31. Dez 2018 08:21

AW: TObjektList mit 2 oder mehr TObjekte
 
Zitat:

Zitat von scrat1979 (Beitrag 1422343)
Zum erkennen wieviele Objekte vom jeweiligen Typ vorhanden sind könntest du folgendes machen (Code inkomplett aber die Vorgehensweise sollte klar sein):

Delphi-Quellcode:
for i:=0 to Count-1 do
 If Items[i] is TSoundRow then...

Hab ich schon gemacht. Damit erhalte ich die Anzahl SoundsRow und SoundCol aber nicht den jeweiligen itemindex so wie man ihn brauch (aus einem Array, oder Liste).
Zitat:

Zitat von hoika (Beitrag 1422344)
Hallo,
warum soll es ein Speicher-Problem geben?
Du schreibst den Speichern-Code ja auch, oder?

Zitat:

Zitat von alfold
Wird hoffentlich kein Problem dann beim Speichern ???.

Mh, bei 2 Objektlisten! Irgendwann sollen die Daten ja gespeichert werden.
Stell ich mir sehr komplex vor dies in eine Datei zu Speichern.

Wie gesagt hab ich noch nie gemacht, bis dato.

Totzdem Danke an alle,
hab jetzt noch ein 2 property hinzugefügt als itemindex.
Hätt ich gleich machen sollen:wink:

Gruß alfold

Aviator 31. Dez 2018 11:15

AW: TObjektList mit 2 oder mehr TObjekte
 
Zitat:

Zitat von alfold (Beitrag 1422345)
hab jetzt noch ein 2 property hinzugefügt als itemindex.
Hätt ich gleich machen sollen:wink:

Dann würde mich jetzt mal interessieren, was bei deinem Programm passiert wenn du folgendes Szenario hast:

  • Du speicherst 10 Objekte in deiner ObjectList.
  • Die zusätzliche Property ItemIndex deiner Objects sind von 0-9 durchnummeriert
  • Du löschst das vierte (oder was auch immer für ein) Element/Object aus der Liste
  • Du durchläufst die Liste und willst irgendein spezielles Object haben. Sagen wir das, bei dem deine ItemIndex Property auf 9 steht
  • Du greifst auf das jetzt 9. Object in der Liste zu und nimmst dir den ItemIndex
  • Der Item Index ist 9, aber der größte Index ist 8, da nur noch 9 Objekte in deiner Liste sind
  • ... probier aus was passiert :)

Ein anderer Fall wäre, dass du auf ein Object mit einem bestimmten ItemIndex zugreifen möchtest, dieses aber in Wirklichkeit von einem anderen Typen ist, da sich durch das Löschen von Elementen die Reihenfolge verschoben hat. Also spätestens beim Cast auf ein anderes Object bzw. beim Zugriff auf eine Property dieses Objects knallt es dann.

Also hast du nur zwei Möglichkeiten:
  1. Du musst jedes Mal wenn du ein Element aus der Liste löschen willst den ItemIndex aller nachfolgenden Elemente korrigieren
  2. Du benutzt einfach zwei unterschiedliche Listen für dein Problem
  3. (Optional: Du machst dir eine eigene Klasse die wiederum in einer generischen TObjectList<T> gespeichert wird und verwaltest dort deine Daten)

alfold 1. Jan 2019 08:50

AW: TObjektList mit 2 oder mehr TObjekte
 
:party: ist vorbei. Ein gutes Neues an alle :party:

Zitat:

Zitat von Aviator (Beitrag 1422352)
Also hast du nur zwei Möglichkeiten:
  1. Du musst jedes Mal wenn du ein Element aus der Liste löschen willst den ItemIndex aller nachfolgenden Elemente korrigieren
  2. Du benutzt einfach zwei unterschiedliche Listen für dein Problem
  3. (Optional: Du machst dir eine eigene Klasse die wiederum in einer generischen TObjectList<T> gespeichert wird und verwaltest dort deine Daten)

Zu 1: Jo so würd ich es auch machen wollen.
zu 2: Hat @jaenicke auch schon geschrieben. Hab ich auch schon dran gedacht. Aber wie löse ich das, wenn die Daten in eine Datei gespeichert und wieder ausgelesen werden sollen? Hab ich auch noch nie gemacht!
zu 3: Delphi 7 Enterprise??

Alle Jubeljahre mal wieder ein kleines Project. Da fängt man immer wieder bei null an:oops: Wollte halt mal mit Objectlist arbeiten. Gerade wegen des abspeichern in eine Datei.

Gruß alfold

scrat1979 1. Jan 2019 10:57

AW: TObjektList mit 2 oder mehr TObjekte
 
Das Speichern von mehreren Listen in eine Datei ist überhaupt kein Problem. Spendiere jedem Object eine SaveToStream-Methode (die musst du selbst schreiben). Eine Objektliste speicherst du dann, indem du zunächst die Anzahl der Elemente in den Stream schreibst und dann durch die Liste durchiterierst und so die einzelnen Objekte schreibst. Das Auslesen geht dann entsprechend umgekehrt.

Mein Sohn blockiert gerade den PC. Auf Wunsch kann ich später mal Code posten.

P.S.: Ebenfalls ein Gutes Neues natürlich :)

scrat1979 1. Jan 2019 13:14

AW: TObjektList mit 2 oder mehr TObjekte
 
Anbei nun ein Beispielcode. Gibt noch andere Ansätze, aber das Grundprinzip sollte klar werden. Mit einer generischen TObjectList<T> wäre es noch eleganter, aber die steht Dir ja bei D7 nicht zur Verfügung...

Voila...

Delphi-Quellcode:
unit TestUnit;

interface

uses Classes, SysUtils, Contnrs;


type TObjekt1 = class(TObject)
  private
    FID   : Integer;
    FValue : Integer;

  public
    property ID   : Integer read FID   write FID;
    property Value : Integer read FValue write FValue;

    procedure SavetoStream(AStream : TStream);
    procedure LoadFromStream(AStream : TStream);

    constructor Create(AID : Integer; AValue : Integer);
end;

type TObjektListe = class(TObjectList)
  public
    procedure LoadFromStream(AStream : TStream);
    procedure SaveToStream(AStream : TStream);

end;

implementation

{ TObjekt1 }

constructor TObjekt1.Create(AID, AValue: Integer);
begin
  FID := AID;
  FValue := AValue;
end;

procedure TObjekt1.LoadFromStream(AStream: TStream);
begin
  AStream.ReadBuffer(FID, SizeOf(FID));
  AStream.ReadBuffer(FValue, SizeOf(FValue));
end;

procedure TObjekt1.SavetoStream(AStream: TStream);
begin
  AStream.WriteBuffer(FID, SizeOf(FID));
  AStream.WriteBuffer(FValue, SizeOf(FValue));
end;

{ TObjektListe }

procedure TObjektListe.LoadFromStream(AStream: TStream);
var FCount : Integer;
  i: Integer;
begin
  (* Liste löschen *)
  Clear;

  (* Anzahl der Elemente auslesen *)
  AStream.ReadBuffer(FCount, SizeOf(Fcount));

  for i := 0 to FCount-1 do begin
    Add(TObjekt1.Create(-1, -1));
    TObjekt1(Last).LoadFromStream(AStream);
  end;
end;

procedure TObjektListe.SaveToStream(AStream: TStream);
var FCount : Integer;
  i: Integer;
begin
  (* Anzahl der Elemente speichern *)
  FCount := Count;
  AStream.WriteBuffer(FCount, SizeOf(FCount));

  (* Einzelne Elemente speichern *)
  for i := 0 to FCount-1 do
    TObjekt1(Items[i]).SavetoStream(AStream);
end;

end.

Aviator 1. Jan 2019 13:17

AW: TObjektList mit 2 oder mehr TObjekte
 
Zitat:

Zitat von alfold (Beitrag 1422383)
zu 3: Delphi 7 Enterprise??

Kannst du dir nicht die kostenlose Delphi Community Version holen? Da hättest du dann alle neuen Sprachfeatures.

alfold 1. Jan 2019 14:17

AW: TObjektList mit 2 oder mehr TObjekte
 
Zitat:

Zitat von scrat1979 (Beitrag 1422393)

Voila...

MH:gruebel: Ich dachte das dies einfacher wäre um alles in eine Datei zu speichern.

Delphi-Quellcode:
procedure TObjekt1.LoadFromStream(AStream: TStream);
begin
  AStream.ReadBuffer(FID, SizeOf(FID));
  AStream.ReadBuffer(FValue, SizeOf(FValue));
end;

procedure TObjekt1.SavetoStream(AStream: TStream);
begin
  AStream.WriteBuffer(FID, SizeOf(FID));
  AStream.WriteBuffer(FValue, SizeOf(FValue));
end;
wenn ich also jeden Parameter einzel aufführen muss, bei mir also

Code:
Soundfile: ShortString;
SoundName: ShortString;
SoundColor: TColor;
CommentText: ShortString;
CommentColor: TColor;
CommentSize: Integer;
SzeneText: ShortString;
SzeneColor: TColor;
ColIndex: Integer;
Start: TTime;
Anfang: TTime;
Ende: TTime;
LoopA: TTime;
LoopE: TTime;
VolA: Integer;
VolE: Integer;
FadeTime: real;
FadeIn: Boolean;
FadeOut: Boolean;
FwStop: Boolean;
und da kommt sicherlich noch was hinzu, ist dies aber auch nicht effektiver als meine alte speichern und lesen Routine, wo ich alles als String umwandle mit ';' trenne dann in eine Datei Speichere und wieder einlese.
Ich dachte das Binär Speichern währe einfacher.

Zitat:

Zitat von Aviator (Beitrag 1422394)
Kannst du dir nicht die kostenlose Delphi Community Version holen? Da hättest du dann alle neuen Sprachfeatures.

Ja mach ich gerade.

Delphi.Narium 1. Jan 2019 17:52

AW: TObjektList mit 2 oder mehr TObjekte
 
Wieviele Instanzen pro Objekt?

Je eine?

Nimm doch 'ne INI-Datei.

Je Objekt 'nen Abschnitt und dort dann die Werte rein.

Alle von Dir aufgeführten Werte können problemlos in 'ne INI-Datei geschrieben werden.

Oder 'ne "Datenbank":

Ein Feld für den Namen des Objektes (oder so) und ein Blob für den Stream.

Es muss übrigens kein "richtiges" DBMS sein, kbmMemTable (http://www.delphibag.com/sol/tkbmmemtable.html) kann sowas (eine CSV-ähnliche Textdatei). Oder TClientDataSet (kennt Delphi 7 auch) hat die Methoden LoadFromFile und SaveToFile. Sollte also auch in Delphi 7 alles vorhanden sein, was Du benötigst.

scrat1979 1. Jan 2019 19:13

AW: TObjektList mit 2 oder mehr TObjekte
 
Naja, also es mag auf den ersten Blick zumindest aufwendig erscheinen, richtig - schwierig würde ich jedoch nicht sagen. Aber das ist bei der OOP ja oft so. Am Anfang deutlich zeitintensiver, die Wartung des Codes gestaltet sich zukünftig jedoch viel einfacher.

Ohne Deine bisherige Schreib- bzw. Leseroutinen zu kennen: Es scheint sich um eine Art Konfiguration zu handeln, welche Du speicherst - also nicht besonders zeitkritisch. Von daher ist es relativ egal was Du dort machst und ob Du vorher in einen String umwandelst. In meinem Code sparst du Dir zumindest die Konvertiertung und somit Rechenzeit.

Ich habe auch ObjectLists mit deutlich mehr Parametern (s. Deine Liste) in den Objekten zu speichern. Aber wenn ich jetzt einen zusätzlichen Parameter brauche dann muss ich nur die LoadFromStream und SaveToStream-Methode des Objekts anpassen und alles läuft und nichts wird woanders übersehen. Alles schön gekapselt wie es sein soll.

Willst Du nun 2 ObjectLists in einen Stream speichern, dann brauchst Du nur

Delphi-Quellcode:
ObjectListe1.SaveToStream(MyStream);
ObjectListe2.SaveToStream(MyStream);
schreiben und die Sache ist gegessen. LoadFromStream entsprechend zum lesen. Schwierig ist anders :-)

Ich gehe noch einen Schritt weiter und benutze die TObjectList<T> nur intern in einer Oberklasse und kapsele die Zugriffe (inkl. Items[x]) von außen. Damit habe ich alle Funktionen welche ich brauche (AddItem, DeleteItem etc.) selbst in der Hand.

alfold 1. Jan 2019 20:50

AW: TObjektList mit 2 oder mehr TObjekte
 
So hab mal die Edition geladen, :shock: Exe gleich mal knapp 3MB groß und noch nicht mal eine Zeile geschrieben. Optisch aber schön.

Ok zurück zum Thema.
Aufwendig ist es nicht! Aber nichts anderes, was ich schon gemacht habe, mit ne einfachen Stringliste um die Werte in eine Datei zu speichern.

Muss aber leider jetzt erst mal wieder abbrechen. Fahre morgen für eine Woche weg und kann mich dann wieder mit meinem Project beschäftigen.

THX an alle

Gruß alfold


Alle Zeitangaben in WEZ +1. Es ist jetzt 11:05 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