Do you want to leverage your Delphi Objects in the Python Scripts with less code? Python4Delphi has the flexibility to do that using a TPyDelphiWrapper component. This benefits Delphi Developers easily to wrap the existing or new Delphi Objects into Python Objects. You can also use Python4Delphi with C++Builder.
Python4Delphi Demo31 Sample App shows how to wrap a Delphi Object to Python Object and Unit test some of the Wrapped Delphi Objects using python script. You can find the Demo31 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 Demo31 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 to add a method of type PyCFunction. You can create events using the Events property.
- TPyDelphiWrapper: Component that wraps the Delphi Object to Python Object inherited from TEngineClient. It has the capability to store Delphi class registration information, registration for Helper Types(not correspond to Delphi Classes), register python module functions, created event handlers. Wrap, WrapRecord, WrapInterface are the key methods to wrap Delphi Object, Record, and Interface respectively.
- 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.
- TActionList maintains a list of actions that can be used by components and controls such as menu items and buttons.
You can find the Python4Delphi Demo131 sample project from the extracted GitHub repository ..Python4DelphiDemosDemo31.dproj. Open this project in RAD Studio 10.4.1 and run the application.
- PyEngine component provides the connection to Python or rather the Python API. This project uses Python3.9 which can be seen in the TPythonEngine DllName property.
- PythonGUIInputOutput component provides a conduit for routing input and output between the Graphical User Interface (GUI) and the currently
executing Python script.
- PyDelphiWrapper component is created dynamically and its Module and Engine Property were associated with spam and PythonEngine respectively. Note: When instantiating TPyDelphiWrapper, we need to call initialize.
procedure TForm1.FormCreate(Sender: TObject);
PyDelphiWrapper := TPyDelphiWrapper.Create(Self); // no need to destroy
PyDelphiWrapper.Engine := PyEngine;
PyDelphiWrapper.Module := PythonModule;
PyDelphiWrapper.Initialize; // Should only be called if PyDelphiWrapper is created at run time
In this sample App, Along with the Delphi Application’s MainForm, TTestClass, TTestRTTIAccess objects were wrapped to python Object and included in a PythonModule with different variables names. Later these variables were imported into the python script and unit tested by the python script in Memo1. Form Creation from Python, Subclassing, Navigation, unit testing is also carried in the Python Script.
procedure TForm1.Button1Click(Sender: TObject);
p : PPyObject;
actTest.OnExecute := actTestExecute;
// Wrap the Form itself.
p := PyDelphiWrapper.Wrap(Self);
PythonModule.SetVar( 'MainForm', p );
// Now wrap the an instance our TestClass
p := PyDelphiWrapper.Wrap(TTestClass.Create, soOwned);
PythonModule.SetVar( 'DVar', p );
// Then wrap the an instance our TTestRTTIAccess
// It will allow us to to test access to public fields and methods as well
// public (as well as published) properties.
p := PyDelphiWrapper.Wrap(TTestRTTIAccess.Create, soOwned);
PythonModule.SetVar( 'rtti_var', p );
p := PyEngine.PyLong_FromLong(Trunc(System.CompilerVersion));
PythonModule.SetVar( 'DelphiVersion', p );
// Excecute the script
PyEngine.ExecStrings( memo1.Lines );