Computing: Free Pascal Programming

Running a Python script from Free Pascal: A brief introduction.


"Why would I want to run a Python script from Free Pascal?", you may ask. The reason is simple: because, in a certain way, these two programming languages are complementary. Free Pascal, thanks to Lazarus, allows to easily and quickly build a graphical user interface. And developing a Python script is (normally) simpler and faster than creating a Pascal program. Also, the interpreted languages have the advantage that we can modify the source code on the fly, no need of a compilation, just making the changes and run the modified version.

Two major cases, thus, to use Lazarus/Free Pascal and Python together: First, we have a Python script, that we want to run as a desktop application (i.e. to run in a GUI); and second, we have a Pascal program, that has to do some calculations that are easier and/or faster to code in Python.

"Python for Delphi (P4D) is a set of free components that wrap up the Python DLL into Delphi and Lazarus (FPC). They let you easily execute Python scripts, create new Python modules and new Python types. You can create Python extensions as DLLs and much more.", they write in the article Python4Delphi on the Free Pascal website. This tutorial is a very short introduction to the subject. In fact, we'll just see two very simple examples:

  1. A Lazarus/Free Pascal application executes a Python script, that does all the calculations and creates the resulting output, that is retrieved in a TMemo object of the calling program.
  2. A Lazarus/Free Pascal application executes a Python script, that does some calculations, returning the results to the calling program, that displays them in some controls of the Lazarus form.

You can download Python for Delphi from Github. Originally written for Delphi, it now works with FPC, too. The download is a ZIP archive. Note, that the actual download version requires Python 3.7, or higher.

In the directory "Packages", you find a subdirectory called FPC, and here you find a Lazarus package called P4DLaz.lpk, that you can easily install using the Lazarus Package Manager (cf. my tutorial Installing supplementary Lazarus/Free Pascal packages). The package installs several visual components, that will be available in a new component group called "Python".

Program sample 1.

The program sample Python4Delphi1 shows how to execute a Python script, stored in a first memo (when some button is pushed), and retrieve the script output in a second memo. The application is based on the first example in Andy Bulka's article Using Delphi and Python together at atug.com.

Before starting to create the GUI, open Project Inspector, and choose Add > New requirement. Scroll down the list of installed packages and select P4DLaz.

The screenshot below shows the form of the Python4Delphi1 application.

Lazarus/Free Pascal and Python: Executing a Python script from a FPC GUI [1]

The nice thing here is that you can run any Python script that you want, the code of this script being exactly the same as if you ran the script from the command line, in particular, you can use a normal print instruction to create the output.

My script creates the 15 first lines of Pascal's Triangle, the triangle display being very rudimentary, just displaying the row arrays. Here is the code (that we place in the upper memo of the Lazarus/Free Pascal application).
    def pascal(n):
        row = [1]
        k = [0]
        for x in range(max(n,0)):
            print(row)
            row=[l+r for l,r in zip(row+k,k+row)]
        return n>=1
    ret = pascal(15)
    if (ret == False):
        print("\nUnexpected error!")

And here is the output of the script, run in Windows Command Prompt.

Lazarus/Free Pascal and Python: Testing the Python script in Windows Command Prompt

To execute a Python script and retrieving its output in a TMemo object (the lower memo, in our case), we need two components from the newly installed "Python" components group: a TPythonEngine object (I called it "pyEngine"), that is the major component of the wrapper, doing "all the work required behind the scenes", so to say, and a TPythonGUIInputOutput object (I called it "PyGuiIO"), that directs all output of the Python script to the TMemo object (that I named "edOutput").

Neither of these two objects has lots of properties, there is only one for each of them that we have to set:

  1. Set the IO property of the TPythonEngine object to the name of the TPythonGUIInputOutput object ("PyGuiIO").
  2. Set the Output property of the TPythonGUIInputOutput object to the name of the memo, where the script output should go to ("edOutput").

All that our Lazarus/Free Pascal application does is executing the script in the upper memo (that I named "edSource"), thus the code is just some lines. Executing some lines of Python code is done by calling the method TPythonEngine.ExecStrings, the argument to pass to the method being of type TStrings (what is nothing else than an array of string), what is also the case of TMemo.Lines. Thus the code for the execution of the script (executed when the button "Run" is pushed), is simply as follows ("fPy4D1" being the name of my form, "btRun", the name of my button):
    procedure TfPy4D1.btRunClick(Sender: TObject);
    begin
        if edSource.Text <> '' then
            pyEngine.ExecStrings(edSource.Lines);
    end;

To be complete, here is the code executed when the "Exit" button (I called it "btExit") is pushed.
    procedure TfPy4D1.btExitClick(Sender: TObject);
    begin
        Close;
    end;

The screenshot shows the execution of the application (the "Run" button having already been pressed).

Lazarus/Free Pascal and Python: Executing a Python script from a FPC GUI [2]

Program sample 2.

The program sample Python4Delphi2 shows how to execute a Python script, stored on the file system, and how to do to pass values between a Free Pascal application and a Python script, in particular how to return values determined by Python to the calling application (that then displays them). The application is based on the second example in Andy Bulka's article Using Delphi and Python together at atug.com.

As before, we start by adding the package P4DLaz as new requirement to our project.

The screenshot below shows the form of the application Python4Delphi2.

Lazarus/Free Pascal and Python: Returning values from a Python script to a Free Pascal application [1]

To execute a Python script and passing values between Free Pascal and Python, we need, of course, a TPythonEngine object (I called it "pyEngine"). As, in our program sample, the Python script doesn't make any output, no input/output object will be needed.

The communication between the Free Pascal application and the Python script is assured by one or more TPythonDelphiVar objects. These objects, defined in the Free Pascal program, are visible to the Python interpreter, thus it can access them, as well to get their value, as to set a new one. You must create a TPythonDelphiVar object for each value, that is passed.

My Python script used in this example is called pythoninfo.py and is stored together with the Free Pascal application. All that it does is to lookup some information concerning the Python interpreter and return these values to the Free Pascal application, that displays them (in edit fields for the Python version and the path to the executable, in a memo for the Python interpreter copyright). We have thus to create 3 TPythonDelphiVar objects; I called them "pyVersion", "pyExecutable", and "pyCopyright" respectively.

The screenshot below shows the property sheet of "pyVersion". There are two properties to fill in:

  1. Set the Name property to the name of the component ("pyVersion").
  2. Set the VarName property to the name that will be used in the Python script to access this object (I set the name of the Python object to "Version").

Lazarus/Free Pascal and Python: Returning values from a Python script to a Free Pascal application [2]

The Python script is elementary: Just retrieving the desired information and assigning it to the Value property of the 3 "Free Pascal" objects.
    import sys
    Version.Value = sys.version
    Executable.Value = sys.executable
    Copyright.Value = sys.copyright

All that the Lazarus/Free Pascal application does is executing the script "pythoninfo.py" (this is done using the method TPythonEngine.ExecFile) and then copy the information that the script has put into the TPythonDelphiVar objects into the form fields. This is actually done when the button "Get info" is pushed. Here is the corresponding code ("fPy4D2" being the name of my form, "btInfo", the name of my button):
    procedure Tfpy4d2.btInfoClick(Sender: TObject);
    begin
        pyEngine.ExecFile('pythoninfo.py');
        repeat
        until pyCopyright.ValueAsString <> '';
        edVersion.Text := pyVersion.ValueAsString;
        edExecutable.Text := pyExecutable.ValueAsString;
        edCopyright.Text := pyCopyright.ValueAsString;
    end;

And here is the code executed when the "Exit" button (I called it "btExit") is pushed.
    procedure TfPy4D2.btExitClick(Sender: TObject);
    begin
        Close;
    end;

Note: I added the repeat ... until loop to be sure that the script is terminated when I do the copy. Maybe, this is not necessary (is the execution of the method code eventually paused until the execution of the script is terminated?).

Here is the screenshot of the program execution. Note, that the edit field, that should contain the path to the Python interpreter actually contains the path to Python4Delphi2.exe instead...

Lazarus/Free Pascal and Python: Returning values from a Python script to a Free Pascal application [3]

Note:Besides Python4Delphi, there is a fork called Python for Lazarus, that you can download from Github. For further information, view the article Using Python in Lazarus on Windows/Linux on the Free Pascal website...


If you find this text helpful, please, support me and this website by signing my guestbook.