Learn How To Build An Iterator Python Type For Delphi In This Windows GUI App
We are aware of how to use TStringList in Delphi. we learned how to create a Python type using Delphi classes. Thinking How to create an iterator in Delphi Which holds python objects? This post guide you to create a Python Type that contains a list of strings(python string objects) similar to TStringList. And a String List Iterator Python Type In Delphi to iterate the StringList Python Type easily in Delphi with Python4Delphi Sample App.
Python4Delphi Demo28 Sample App shows how to create a StringList Python type, StringList Iterator Python Type in a Python Module, Import the module, and Iterator Python Types in a python script, create a Stringlist object and access some of the service routines like Iter, IterNext, etc. You can find the Demo28 source on GitHub.
Prerequisites: Download and install the latest Python for your platform. Follow the Python4Delphi installation instructions mentioned here. Alternatively, you can check out this video Getting started with Python4Delphi.
Components used in Python4Delphi Demo28 Sample App:
- TPythonEngine: A collection of relatively low-level routines for communicating with Python, creating Python types in Delphi, etc. It’s a singleton class.
- TPythonGUIInputOutput: Inherited from TPythonInputOutput (which works as a console for python outputs) Using this component Output property you can associate the Memo component to show the Output.
- TPythonModule: It’s inherited from TMethodsContainer class allows creating modules by providing a name. You can use routines AddMethod, AddMethodWithKW, AddDelphiMethod, AddDelphiMethodWithKeywords to add a method which should be type compatible with this routine parameter. You can create events using the Events property.
- TPythonType: This component helps to create a new python type in Delphi which is inherited from the hierarchy of classes (set of APIs to create, manage methods, and members).
- TMemo: A multiline text editing control, providing text scrolling. The text in the memo control can be edited as a whole or line by line.
You can find the Python4Delphi Demo28 sample project from the extracted repository ..Python4DelphiDemosDemo28.dproj. Open this project in RAD Studio 10.4.1 and run the application.
Implementation Details:
- PythonEngine1 provides the connection to Python or rather the Python API. This project uses Python3.9 which can be seen in the TPythonEngine DllName property.
- PythonGUIInputOutput1 provides a conduit for routing input and output between the Graphical User Interface (GUI) and the currently
executing Python script. - pmP4D with a Module name p4d is created.
- Python Type (ptStringList) with Type Name TStringList and Python type (ptStringListIterator) with Type Name TStringListIterator is created. Both Python Types Module Property is assigned with pmP4D.
- Each Python Type PyObjectClass is initialized with Delphi Python Type Class as shown below.
procedure TForm1.ptStringListIteratorCreate(Sender: TObject);
begin
with Sender as TPythonType do
PyObjectClass := TPyStringListIterator;
end;
procedure TForm1.ptStringListCreate(Sender: TObject); begin with Sender as TPythonType do PyObjectClass := TPyStringList; end;
procedure TForm1.ptStringListIteratorCreate(Sender: TObject); begin with Sender as TPythonType do PyObjectClass := TPyStringListIterator; end; |
In this sample, TPyStringList overrides the Iter, Basic service of TPyObject, and Sequence Services such as SqLength, SqItem, SqAsItem. Using RegisterMethods exposed an Add method(Using this a string can be added to the string list). Used PyArg_ParseTuple to retrieve the arguments passed in python scripts. This class also has the property to return TStringList.
function TPyStringList.add(args: PPyObject): PPyObject; var _obj : PPyObject; begin with GetPythonEngine do begin // We adjust the transmitted self argument Adjust(@Self); if PyArg_ParseTuple( args, ‘O:add’,@_obj ) > 0 then begin Result := PyLong_FromLong(Strings.Add(PyObjectAsString(_obj))); end else Result := nil; end; end; |
TPyStringListIterator overrides Iter, IterNext Basic services of TPyObject. Using RegisterMethods exposed a Next method(Using this the next item in the TPyStringList can be retrieved).
function TPyStringListIterator.next(args: PPyObject): PPyObject; begin with GetPythonEngine do begin // We adjust the transmitted self argument Adjust(@Self); Result := Self.IterNext; if not Assigned(Result) and (PyErr_Occurred = nil) then PyErr_SetString(PyExc_StopIteration^, ‘Stop iteration’); end; end; |
On Clicking Execute Button the below python scripts is executed. These 2 Python Types were instantiated in the python scripts and accessed as shown below.
i = iter(L)
print (i)
try:
while True:
print (i.next())
except StopIteration:
print (“Done”)
print (L[2])
L[2] = int(L[2]) * 2
print (L[2], type(L[2]))
print (L[ L.add(10) ])
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
import p4d L = p4d.CreateTStringList(1, 2, 3, 4) print (L) for i in L: print (i, type(i))
i = iter(L) print (i) try: while True: print (i.next()) except StopIteration: print (“Done”)
print (L[2]) L[2] = int(L[2]) * 2 print (L[2], type(L[2])) print (L[ L.add(10) ]) |
Note. CreateTStringList in the above script is defined automatically by Python4Delphi when the property GenerateCreateFunction of ptStringList is true.