Earlier we have seen how to add methods in Python Module using Python4Delphi TPythonModule component’s Add Method. However, the Add Method parameter uses a PyCFunction type parameter. In many cases, we may need to define the method which should return Delphi Type. How to do that? This post will provide a way to do that using the TPythonModule component itself. You can also use Python4Delphi with C++Builder.
Python4Delphi Demo7 Sample App shows how to create a Module, add a Delphi Method to that module, Import the module in a python script, and access the added routine. You can find the Demo7 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 Demo5 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 AddDelphiMethod, AddDelphiMethodWithKW to add a method of TDelphiMethod type. The difference between using AddMethod and AddDelphiMethod is the method parameter type which uses PyCFunction and TDelphiMethod respectively. You can create events using the Events property.
- 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.
Note: This Demo also uses TPythonType component but this post doesn’t cover that. To learn about TPythonType check this post.
You can find the Python4Delphi Demo7 sample project from the extracted GitHub repository ..Python4DelphiDemosDemo07.dproj. Open this project in RAD Studio 10.4.1 and run the application.
Implementation Details:
- PythonEngine1 component provides the connection to Python or rather the Python API. This project uses Python3.9 which can be seen in TPythonEngine DllName property. It Is assigned with InitScript which import sys module and prints the Python.Dll version, copyright information to Memo2 using this InitScript. import sys print(“Python Dll: “, sys.version) print(sys.copyright) print()
- PythonGUIInputOutput1 component provides a conduit for routing input and output between the Graphical User Interface (GUI) and the currently executing Python script.
- PythonModule1 with Module name spam is created. During PythonModule1Initialization a method spam_getdouble and spam_getdouble2 is added to the Module. And the definition of the method is included in the same unit file. Logically a python module is created and its methods were created using this PythonModule. Later this can be imported into your python script wherever necessary.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
procedure TForm1.PythonModule1Initialization(Sender: TObject); begin // In a module initialization, we just need to add our // new methods with Sender as TPythonModule do begin AddDelphiMethod( 'foo', spam_foo, 'foo' ); AddDelphiMethod( 'CreatePoint', spam_CreatePoint, 'function CreatePoint'+LF+ 'Args: x, y'+LF+ 'Result: a new Point object' ); AddDelphiMethod( 'getdouble', spam_getdouble, 'getdouble' ); AddDelphiMethod( 'getdouble2', spam_getdouble2, 'getdouble2' ); end; end; |
- Memo1, used for providing the Python Script which imports spam (PythonModule1), accesses the method spam_getdouble( uses Py_BuildValue) and spam_getdouble2 (uses ArrayToPyTuple) and prints the output in Memo2. Buttons to perform the execution, load script from, and save the script to file.
- On Clicking Execute Script Button, the below script is executed.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
import sys print ("Version:", sys.version) import spam print (spam.foo('hello world', 1)) p = spam.CreatePoint( 10, 25 ) print ("Point:", p) p.x = 58 print (p.x, p) p.OffsetBy( 5, 5 ) print (p) print ("Current value of var test is: ", test) test.Value = "New value set by Python" print (spam.getdouble()) print (spam.getdouble2()) |
Check some of the tutorials available for Python4Delphi here