TList Eintrag verändern, nicht löschen!

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
multiplatform-coder
Beiträge: 61
Registriert: Do 20. Apr 2023, 18:25

TList Eintrag verändern, nicht löschen!

Beitrag von multiplatform-coder »

Hallo

irgendwas muss mir entgangen sein, habe auch TList lange nicht mehr verwendet.

Ich habe eine Klaase vom Typ TList, ich die ich nun Einträge einbringen will, die ich im Programmlauf veränern will. Im konkteten Fall handelt es sich um Boolean Werte. Ich suche aber schon eine alllgemein anwendbare Methode, wie ich die Boolan Werte meiner Listeneinträge zur Laufzeit andern kann.

Code: Alles auswählen


Type
   tmyListItem = class
      my_boolean_value: boolean;
      my_other_values: any_Type;
   end;
   tMyList = class(TList)
      function GetListItem(Index: Integer): tMyListItem;
      procedure SetListItem(Index: Integer, Value: tMyListItem);
      property ListItems[Index: Integer]: TmyListItem read GetListItem write SetListItem;
   end;
   
   function GetListItem(Index: Integer): tmyListItem;
   begin
      Result := tmyListItem(Items[Index]);
   end;
   
    procedure SetListItem(Index: Integer, Value: tMyListItem);
    begin
        tmyListItem(Items[Index]) := Value;     //Diese Zuweisung funktioniert nicht, da TList.Items[] eine NUR LESEN EIGENSCHAFT ist.
    end;
    
    
    Wie kann ich die Werte der Liste dennoch verändern?

Benutzeravatar
Jorg3000
Lazarusforum e. V.
Beiträge: 398
Registriert: So 10. Okt 2021, 10:24
OS, Lazarus, FPC: Win64
Wohnort: NRW

Re: TList Eintrag verändern, nicht löschen!

Beitrag von Jorg3000 »

Hi!
TList.Items[] hat nicht nur eine Lesen-Eigenschaft.
Versuch mal Folgendes ...

Code: Alles auswählen

 
   Items[Index] := Pointer(Value);
 

Benutzeravatar
Zvoni
Beiträge: 412
Registriert: Fr 5. Jul 2024, 08:26
OS, Lazarus, FPC: Windoof 10 Pro (Laz 2.2.2 FPC 3.2.2)
CPU-Target: 32Bit
Wohnort: BW

Re: TList Eintrag verändern, nicht löschen!

Beitrag von Zvoni »

Items ist sicher nicht Read-Only.
Worüber du wahrscheinlich stolperst, ist das die Items-Property einen Pointer zurückgibt auf das eigentlich Item

https://www.freepascal.org/docs-html/rt ... items.html
*gelöscht*
ich Depp hatte übersehen, dass TMyItem ja eine Class ist (was an sich ja schon ein Zeiger ist).
Jörg hats richtig.

Wobei: Wieso eine Class? Wieso nicht stumpf nen Record?
Spart man sich das dauernde TMyItem.Create blablabla

Ich frage mich gerade eher, wieso der Compiler bei dem hier nicht motzt:

Code: Alles auswählen

procedure SetListItem(Index: Integer, Value: tMyListItem);
Ein System sie alle zu knechten, ein Code sie alle zu finden,
Eine IDE sie ins Dunkel zu treiben, und an das Framework ewig zu binden,
Im Lande Redmond, wo die Windows drohn.

multiplatform-coder
Beiträge: 61
Registriert: Do 20. Apr 2023, 18:25

Re: TList Eintrag verändern, nicht löschen!

Beitrag von multiplatform-coder »

Ich erhalte aber den Fehler "argument cannot be assigned to"

In meiner Set Methode weise ich eine Instanz meiner Klasse zu. Im späteren Programmtext, der den Wert verändern soll, refernziere ich mein Datenfeld.


ListItems[Index] gibt mir einen Zeiger auf die Klasse tmyListItem zurück. Da sollte ich doch auf ListItems[Index].my_boolean_value zugreifen können.

In meiner Set MEthode erhalte ich aber den oben genannten Compiler Fehler.


@Zvoni: Wieso eine Class? Wieso nicht stumpf nen Record?

Kann ich in Zukunft bedenken, in meinem konkreten Fall handelt es sich aber um eine Klasse in einem Programm, deren Daten zur Laufzeit verändert werden sollen
Zuletzt geändert von multiplatform-coder am Mi 26. Mär 2025, 16:20, insgesamt 1-mal geändert.

Benutzeravatar
theo
Beiträge: 10938
Registriert: Mo 11. Sep 2006, 19:01

Re: TList Eintrag verändern, nicht löschen!

Beitrag von theo »

Das ist eigentlich ein klassischer Fall für Generics.
Z.B.:

Code: Alles auswählen

uses fgl;

type

     TMyClass = class(TObject)
       my_boolean_value: boolean;
       my_other_values: String;
     end;

     TMyList = specialize TFPGObjectList<TMyClass>;   

....

var list : TMyList;
  c : TMyClass;
begin
  list := TMyList.Create;
  c := TMyClass.Create;
  c.my_other_values := 'c1';
  list.Add(c);
  c := list[0];
  c.my_other_values:='test';
  ShowMessage(c.my_other_values);
  .....
  list.free;
end;   

multiplatform-coder
Beiträge: 61
Registriert: Do 20. Apr 2023, 18:25

Re: TList Eintrag verändern, nicht löschen!

Beitrag von multiplatform-coder »

@theo: Das muss ich gesondert testen. Generis werden im mir vorliegenden Quellcode nicht verwendet.

Weshalb aber funktionirt das besser? Will nicht einfach Tipps übernehmen sondern auch verstehen.

Allerdings kennt meine Lazarus Version das Wort specialize nicht. Brauche ich da eine besondere Compilereinstrellung oder eine neuere Lazarus Version?
Zuletzt geändert von multiplatform-coder am Mi 26. Mär 2025, 16:34, insgesamt 1-mal geändert.

Benutzeravatar
theo
Beiträge: 10938
Registriert: Mo 11. Sep 2006, 19:01

Re: TList Eintrag verändern, nicht löschen!

Beitrag von theo »

multiplatform-coder hat geschrieben: Mi 26. Mär 2025, 16:22 Weshalb aber funktionirt das besser? Will nicht einfach Tipps übernehmen sondern auch verstehen.
Weil du dir damit die Arbeit sparen kannst, an der du gerade herumdokterst.
Du bestimmst einfach von welchem Typ die Liste ist und gut.

Code: Alles auswählen

TMyList = specialize TFPGObjectList<TMyClass>;   

multiplatform-coder
Beiträge: 61
Registriert: Do 20. Apr 2023, 18:25

Re: TList Eintrag verändern, nicht löschen!

Beitrag von multiplatform-coder »

Habe gerade bei mir nachgeguckt, habe Freepascal 3.2.2 , Lazarus Version 2.2.2

Dieses Forum sagt mir, dass ich da updaten muss: https://forum.lazarus.freepascal.org/in ... ic=68227.0


Aber wo kriege ich ein aktuelle und stabile Version her? Ich will nicht mit einer experimentellen Version rumbasteln. Aus der Lazarus Homepage werde ich nicht schlau
Zuletzt geändert von multiplatform-coder am Mi 26. Mär 2025, 17:07, insgesamt 1-mal geändert.

Benutzeravatar
theo
Beiträge: 10938
Registriert: Mo 11. Sep 2006, 19:01

Re: TList Eintrag verändern, nicht löschen!

Beitrag von theo »

:?:
Wie kommst du denn da drauf?
Funktioniert das Bsp. bei dir nicht?
https://wiki.freepascal.org/Generics

multiplatform-coder
Beiträge: 61
Registriert: Do 20. Apr 2023, 18:25

Re: TList Eintrag verändern, nicht löschen!

Beitrag von multiplatform-coder »

@theo: nein, leider nicht. Ab welcher Freepascal Version sollte denn das funktionieren, ich benutze noch die Version 3.2.2. Habe auch soeben mode Delphi statt Mode objfpc eingestellt, geht aber auch nicht, specialize kennt der Compiler nicht. Oder ich mudd ie Unit fgl einbinden, das mache ich jetzt mal
Zuletzt geändert von multiplatform-coder am Mi 26. Mär 2025, 18:00, insgesamt 1-mal geändert.

Benutzeravatar
theo
Beiträge: 10938
Registriert: Mo 11. Sep 2006, 19:01

Re: TList Eintrag verändern, nicht löschen!

Beitrag von theo »

multiplatform-coder hat geschrieben: Mi 26. Mär 2025, 17:10 @theo: nein, leider nicht. Ab welcher Freepascal Version sollte denn das funktionieren, ich benutze noch die Version 3.2.2. Habe auch soeben mode Delphi statt Mode objfpc eingestellt, geht aber auch nicht, specialize kennt der Compiler nicht.
Mit 3.2.2 muss es gehen. Wie lautet die Fehlermeldung ganz genau (Kopieren).

multiplatform-coder
Beiträge: 61
Registriert: Do 20. Apr 2023, 18:25

Re: TList Eintrag verändern, nicht löschen!

Beitrag von multiplatform-coder »

In meiner Klasse habre ich alleridings ein Datenfeld vom Typ TMyList.

type TMyClass = class
Controls: TMyList;
end;
TMyList = specialize TFPGObjectList<TMyClass>;

Die brauche ich weil ich eine Liste von Controls oder Datenfeldern in meine TMyClass speichern will, dies Listen von Controls sollen dann in eine zweite Liste. Wie ein zwei dimensionales Array.

Code: Alles auswählen

    TMyClass=class;
    TMyList = specialize TFPGObjectList<TMyClass>; 
    TmyClass = class  //Inhalt (Controls) 
    private
      FControls: TMyList;
      FControlsCount: Integer;
      function GetControls(Index: Integer): TControl;
      procedure SetControls(Index: Integer; AValue: TControl);
    public
       procedure AddControl(c: TControl);
       constructor Create;
       property ControlsCount: Integer read FControlsCount;
       property Controls[Index: Integer]: TControl read GetControls write SetControls;  //so würde ich es ohne Generics machen
    end;
    
    
    
Mit eingebundener fgl Unit erkennt der Compiler nun auch specialize. Habe in der Anleitung auch gesehen dass ich wohl nun gabz einfach

MyList[Index] aufrufen kann und einen Item vom Typ TMyClass erhalte, womit ich dann mein Control erhalten sollte und hoffenlich auch dessen Inhalt verändern kann. Ist das richtig?

TmyList solll mehrere Objekte von TMyClass erhalten. die jeweils mehrere Controls (Datenfelder. ...) enthalten die je Listeneintrag ansere Werte bekommen sollen. Wie ein 2 Dimensionales Array.

Spontan fällt mit dazu das Lazarus PageControl Obkekt ein. Da würde man doch für die Tabseiten eine Liste anlegen die die Controls auf jeder Seite speichert. Jetzt mal unabhängig von der tatsächlichen Implementation. Modellhaft für mein Problem soll das aber mal so sein.

oder auch eine Datenbank Eingabemaske bei der die erste Liste die Datenfelder und die zweite die Datensätze referenziert. Gibt sicher noch mehr Anwendungen für derartige Datenstrukturen!

.
Zuletzt geändert von multiplatform-coder am Mi 26. Mär 2025, 19:12, insgesamt 3-mal geändert.

Benutzeravatar
theo
Beiträge: 10938
Registriert: Mo 11. Sep 2006, 19:01

Re: TList Eintrag verändern, nicht löschen!

Beitrag von theo »

multiplatform-coder hat geschrieben: Mi 26. Mär 2025, 18:11 In meiner Klasse habre ich alleridings ein Datenfeld vom Typ TMyList.

type TMyClass = class
Controls: TMyList;
end;
TMyList = specialize TFPGObjectList<TMyClass>;

Da gibt es dann eine Kreuzreferenz.

Code: Alles auswählen

type

TMyClass = Class;

TMyList = specialize TFPGObjectList<TMyClass>;

TMyClass = Class
  Controls: TMyList;
end;    

multiplatform-coder
Beiträge: 61
Registriert: Do 20. Apr 2023, 18:25

Re: TList Eintrag verändern, nicht löschen!

Beitrag von multiplatform-coder »

@theo: ah ok. danke!

multiplatform-coder
Beiträge: 61
Registriert: Do 20. Apr 2023, 18:25

Re: TList Eintrag verändern, nicht löschen!

Beitrag von multiplatform-coder »

Ich bleibe nun erst mal bei meiner aktuellen, nicht geupdateten Lazarusversion, da Generics auch bei meiner Version funktionieren unit fgl macht es möglich. Nun muss ich allerdings meinen Entwurf anpassen. Das schaffe ich entweder alleine oder nerve hier nochmals mit Fragen. Aber das passiert nur wenn ich irgendwo immer noch nicht weiter kommen sollte. Aber mogen ist auch noch ein Tag.

Danke zunächst für Eure Hilfe.

Antworten