Recent

Author Topic: TStringList with objects  (Read 12040 times)

mtanner

  • Sr. Member
  • ****
  • Posts: 287
TStringList with objects
« on: February 21, 2022, 03:31:19 pm »
Not sure if this is the right section of the forum.
I am using a TStringList, adding lines of text, and some lines have an object associated with them, with Add or AddObject. This works fine, and I can retrieve individual lines of text ok.

But I cannot figure out how to retrieve an object associated with a line. I'be looked at the code and all the documentation that I can find. Could someone please just respond with a single line of code that retrieves the object assocuated with a specifie line in the TStringList?

I have tried things like
mylist.objects;
mylist.object;
mylist.GetObject(I);
mylist.GetObject;

but all of these are apparently wrong. I've seen lots of stuff about using TStringList, intriductory to very complex, but cannot find the answer to the above seemingly trivial question.
FI

Zvoni

  • Hero Member
  • *****
  • Posts: 2327
Re: TStringList with objects
« Reply #1 on: February 21, 2022, 03:38:39 pm »
??
Untested! https://www.freepascal.org/docs-html/rtl/classes/tstrings.objects.html
Code: Pascal  [Select][+][-]
  1. Var
  2.    MyClass : TMyClass;  //Or TObject
  3. Begin
  4.    MyClass:=TMyClass(MyList.Objects[SomeValidIndex]);  //If it's TObject above, no need for Casting
  5. End;
  6.  
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad

Sieben

  • Sr. Member
  • ****
  • Posts: 310
Re: TStringList with objects
« Reply #2 on: February 21, 2022, 03:39:21 pm »
The corresponding object of

Code: Pascal  [Select][+][-]
  1. mylist.Strings[i]

is

Code: Pascal  [Select][+][-]
  1. mylist.Objects[i]

It returns a TObject, so if you want to access the class you initially put there you have to use a typecast as Zvoni already mentioned. And as you wrote that only some lines are associated with an object, you'd better test like this:

Code: Pascal  [Select][+][-]
  1. if Assigned(myList.Objects[i]) then  // equivalent to: if (myList.Objects[i] <> nil) then
  2.   myclass := TMyClass(myList.Objects[i]);

or, even better:

Code: Pascal  [Select][+][-]
  1. if (myList.Objects[i] is TMyClass) then
  2.   myclass := TMyClass(myList.Objects[i]);

The 'is'-test tests for nil as well. And you know for sure that it is actually of the class you want and expect.
« Last Edit: February 21, 2022, 03:51:04 pm by Sieben »
Lazarus 2.2.0, FPC 3.2.2, .deb install on Ubuntu Xenial 32 / Gtk2 / Unity7

mtanner

  • Sr. Member
  • ****
  • Posts: 287
Re: TStringList with objects
« Reply #3 on: February 21, 2022, 04:06:48 pm »
Thank you.

Handoko

  • Hero Member
  • *****
  • Posts: 5150
  • My goal: build my own game engine using Lazarus
Re: TStringList with objects
« Reply #4 on: February 21, 2022, 04:33:29 pm »
I'm late. But I hope this demo can be helpful maybe for others:

Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, Forms, Controls, Dialogs, StdCtrls;
  9.  
  10. type
  11.  
  12.   { TForm1 }
  13.  
  14.   TForm1 = class(TForm)
  15.     Button1: TButton;
  16.     CheckBox1: TCheckBox;
  17.     Label1: TLabel;
  18.     Memo1: TMemo;
  19.     RadioButton1: TRadioButton;
  20.     procedure Button1Click(Sender: TObject);
  21.     procedure CheckBox1Click(Sender: TObject);
  22.     procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
  23.     procedure FormCreate(Sender: TObject);
  24.     procedure Memo1Change(Sender: TObject);
  25.     procedure RadioButton1Click(Sender: TObject);
  26.   private
  27.     Info: TStringList;
  28.     procedure SetLink;
  29.     function WhichLine(TheObject: TObject) : string;
  30.   end;
  31.  
  32. var
  33.   Form1: TForm1;
  34.  
  35. implementation
  36.  
  37. {$R *.lfm}
  38.  
  39. { TForm1 }
  40.  
  41. procedure TForm1.FormCreate(Sender: TObject);
  42. begin
  43.   Info := TStringList.Create;
  44.   SetLink;
  45. end;
  46.  
  47. procedure TForm1.Memo1Change(Sender: TObject);
  48. begin
  49.   SetLink;
  50. end;
  51.  
  52. procedure TForm1.RadioButton1Click(Sender: TObject);
  53. begin
  54.   ShowMessage(WhichLine(CheckBox1));
  55. end;
  56.  
  57. procedure TForm1.FormClose(Sender: TObject; var CloseAction: TCloseAction);
  58. begin
  59.   Info.Free;
  60. end;
  61.  
  62. procedure TForm1.Button1Click(Sender: TObject);
  63. begin
  64.   ShowMessage(WhichLine(Button1));
  65. end;
  66.  
  67. procedure TForm1.CheckBox1Click(Sender: TObject);
  68. begin
  69.   ShowMessage(WhichLine(CheckBox1)); // Sorry, does not work on GTK2
  70. end;
  71.  
  72. procedure TForm1.SetLink;
  73. var
  74.   i: Integer;
  75. begin
  76.  
  77.   Info.Clear;
  78.   Info.Assign(Memo1.Lines);
  79.  
  80.   if Info.Count > 0 then
  81.     Info.Objects[0] := Button1;
  82.   if Info.Count > 1 then
  83.     Info.Objects[1] := CheckBox1;
  84.   if Info.Count > 2 then
  85.     Info.Objects[2] := RadioButton1;
  86.   if Info.Count > 3 then
  87.     Info.Objects[3] := Label1;
  88.  
  89.   Button1.Hint      := '';
  90.   CheckBox1.Hint    := '';
  91.   RadioButton1.Hint := '';
  92.   Label1.Hint       := '';
  93.   for i := 0 to Info.Count-1 do
  94.     (Info.Objects[i] as TControl).Hint := Info[i];
  95.  
  96. end;
  97.  
  98. function TForm1.WhichLine(TheObject: TObject): string;
  99. var
  100.   Index: Integer;
  101.   i:     Integer;
  102. begin
  103.   Index := -1;
  104.   for i := 0 to Info.Count-1 do
  105.     if Info.Objects[i] = TheObject then
  106.     begin
  107.       Index := i;
  108.       Break;
  109.     end;
  110.   if Index < 0 then Exit;
  111.   Result := 'Index of the line associated is = ' + Index.ToString;
  112. end;
  113.  
  114. end.
« Last Edit: February 21, 2022, 04:43:32 pm by Handoko »

jcmontherock

  • Full Member
  • ***
  • Posts: 236
Re: TStringList with objects
« Reply #5 on: February 21, 2022, 04:47:00 pm »
Add and retrieve objects in TStringList work fine. The only limitation is with "SaveToFile" and "LoadFromFile": object are not saved to file.
Windows 11 UTF8-64 - Lazarus 3.2-64 - FPC 3.2.2

BeniBela

  • Hero Member
  • *****
  • Posts: 906
    • homepage
Re: TStringList with objects
« Reply #6 on: February 21, 2022, 07:33:19 pm »
TStringList can do everything a little, but nothing well

So it is always a bad idea to use TStringList anywhere

howardpc

  • Hero Member
  • *****
  • Posts: 4144
Re: TStringList with objects
« Reply #7 on: February 21, 2022, 07:37:01 pm »
What class(es) would you suggest as an improvement on TStringList, and how are they better?

Zvoni

  • Hero Member
  • *****
  • Posts: 2327
Re: TStringList with objects
« Reply #8 on: February 22, 2022, 08:28:40 am »
TStringList can do everything a little, but nothing well

So it is always a bad idea to use TStringList anywhere
What are you using TStringList for?
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad

PascalDragon

  • Hero Member
  • *****
  • Posts: 5462
  • Compiler Developer
Re: TStringList with objects
« Reply #9 on: February 22, 2022, 09:06:19 am »
TStringList can do everything a little, but nothing well

So it is always a bad idea to use TStringList anywhere

Such generalized statements aren't helpful. So please provide specific reasons why you think that.

egsuh

  • Hero Member
  • *****
  • Posts: 1289
Re: TStringList with objects
« Reply #10 on: February 22, 2022, 09:46:03 am »
If you are looking for an object connected to a specific string, you may need following.


myobject := mylist.objects[MyList.IndexOf('Your specific string')];

SymbolicFrank

  • Hero Member
  • *****
  • Posts: 1313
Re: TStringList with objects
« Reply #11 on: February 22, 2022, 09:53:32 am »
I like TStringList, it's the object I use most, in general. It can do many useful things.

Yes, I could make a custom class for each implementation, that is probably a bit more efficient and to the point, but it takes more time and the result will be the same.

Thaddy

  • Hero Member
  • *****
  • Posts: 14364
  • Sensorship about opinions does not belong here.
Re: TStringList with objects
« Reply #12 on: February 22, 2022, 10:35:15 am »
What class(es) would you suggest as an improvement on TStringList, and how are they better?
Any generic map or dictionary? Because they are type safe for all elements. But you know all that....
Object Pascal programmers should get rid of their "component fetish" especially with the non-visuals.

jcmontherock

  • Full Member
  • ***
  • Posts: 236
Re: TStringList with objects
« Reply #13 on: February 22, 2022, 11:32:41 am »
I found "AddObject", "InsertObject", but I didn't find "DeleteObject". Do you have any idea for deleting an object ? Maybe "Reduce" ?
« Last Edit: February 22, 2022, 11:47:56 am by jcmontherock »
Windows 11 UTF8-64 - Lazarus 3.2-64 - FPC 3.2.2

Zvoni

  • Hero Member
  • *****
  • Posts: 2327
Re: TStringList with objects
« Reply #14 on: February 22, 2022, 12:07:55 pm »
I found "AddObject", "InsertObject", but I didn't find "DeleteObject". Do you have any idea for deleting an object ? Maybe "Reduce" ?
???
Not tested.....
Code: Pascal  [Select][+][-]
  1.   MyList.Objects[SomeValidIndex].Free;
  2.   //FreeAndNil(MyList.Objects[SomeValidIndex]);
  3.  
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad

 

TinyPortal © 2005-2018