![1527297 | Embarcadero RAD Studio Delphi C++Builder Blogs](https://i0.wp.com/blogs.embarcadero.com/wp-content/uploads/2020/08/1527297.jpg?resize=1140%2C694&ssl=1)
Earlier we know how to create a Thread Inside Python for a Delphi App. However, we didn’t attempt to stop the thread while running. How to stop the thread inside python for a Delphi App with Python4Delphi? This post will help to understand better with the sample. You can also use Python4Delphi with C++Builder to build Python GUI apps on Windows.
Python4Delphi Demo33 Sample App shows how to achieve concurrency(using more interpreters) inside Python and stop in between while threads were running. You can find the Demo33 source on GitHub. This sample is a continuation of Demo11.
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 Demo33 App:
- TPythonEngine: A collection of relatively low-level routines for communicating with Python, creating Python types in Delphi, etc. It’s a singleton class.
- 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.
- TPaintBox provides a canvas that applications can use for rendering an image.
- TPyDelphiThread: Inherited from TThread has properties like ThreadState( A pointer which stores Python last state), ThreadExecMode(emNewState, emNewInterpreter). Protected functions like ExecuteWithPython, Py_Begin_Allow_Threads, Py_End_Allow_Threads helps to run concurrently without thread conflicts.
- 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 Demo33 sample project from the extracted GitHub repository ..Python4DelphiDemosDemo33.dproj. Open this project in RAD Studio 10.4.1 and run the application.
Implementation Details:
- PythonEngine 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.
- SortModule(TPythonModule) has initialized with 2 Delphi Methods SortModule_GetValue, SortModule_Swap which is imported in python script to perform sorting. 3 arrays are randomized with integer values, later get sorted. Three Sort functions were defined in the script such as BubbleSort, SelectionSort, and QuickSort which is evaluated by PyDelphiThread Instance’s ExecuteWithPython procedure. Note: Don’t override Execute Method, use always ExecuteWithPython.
In this Sample, Three thread instance were created and initialized with execution mode as shown below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
procedure TThreadSortForm.InitThreads(ThreadExecMode: TThreadExecMode; script: TStrings); begin RandomizeArrays; ThreadsRunning := 3; with GetPythonEngine do begin OwnThreadState := PyEval_SaveThread; Thread1 := TSortThread.Create( ThreadExecMode, script, SortModule, 'SortFunc1', BubbleSortBox, BubbleSortArray); Thread1.OnTerminate := ThreadDone; Thread2 := TSortThread.Create( ThreadExecMode, script, SortModule, 'SortFunc2', SelectionSortBox, SelectionSortArray); Thread2.OnTerminate := ThreadDone; Thread3 := TSortThread.Create( ThreadExecMode, script, SortModule, 'SortFunc3', QuickSortBox, QuickSortArray); Thread3.OnTerminate := ThreadDone; end; Start1Btn.Enabled := False; Start3Btn.Enabled := False; end; |
one interpreter Button uses an emNewState(single interpreter with new state and upon execution completion, restores the thread state) ThreadExecMode, and three interpreter buttons use an emNewInterpreter (same as a new state but with new interpreter fully initialized) ThreadExecMode to Execute.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
procedure TThreadSortForm.Start1BtnClick(Sender: TObject); begin with GetPythonEngine do begin ExecStrings(PythonMemo.Lines); self.InitThreads(emNewState, nil); end; end; procedure TThreadSortForm.Start3BtnClick(Sender: TObject); begin InitThreads(emNewInterpreter, PythonMemo.Lines); end; |
When all the thread is executed the OwnThreadState is restored.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
procedure TThreadSortForm.ThreadDone(Sender: TObject); begin Dec(ThreadsRunning); if ThreadsRunning = 0 then begin GetPythonEngine.PyEval_RestoreThread(OwnThreadState); Start1Btn.Enabled := True; Start3Btn.Enabled := True; ArraysRandom := False; Thread1 := nil; Thread2 := nil; Thread3 := nil; end; end; |
On Clicking one interpreter or three interpreter button, the three thread is initialized and executes python script by the TSortThread.ExecuteWithPython procedure. Upon execution, the 3 PaintBox’s is get updated by the TSortThread.VisualSwap procedure.
The threads can be stopped manually, by clicking the stop interpreters button Which stops the interpreters which are running using the below code.
1 2 3 4 5 6 |
procedure TThreadSortForm.StopBtnClick(Sender: TObject); begin if Assigned(Thread1) and not Thread1.Finished then Thread1.Stop(); if Assigned(Thread2) and not Thread2.Finished then Thread2.Stop(); if Assigned(Thread3) and not Thread3.Finished then Thread3.Stop(); end; |
In the sample output, the three interpreters button is clicked first and followed by stop interpreters.
![Demo332594493 | Embarcadero RAD Studio Delphi C++Builder Blogs demo33 2594493](https://i0.wp.com/blogs.embarcadero.com/wp-content/uploads/2020/12/Demo33-2594493.png?resize=750%2C406&ssl=1)
Design. Code. Compile. Deploy.
Start Free Trial Upgrade Today
Free Delphi Community Edition Free C++Builder Community Edition