Jump to content
Sign in to follow this  
KoRiF

Python/Delphi synchronization

Recommended Posts

I gonna run python script in separate thread. My PythonEngine has IO field assigned with TPythonGUIInputOutput component

 

What is the correct way to synchronize output (e.g. print("Hello World!") to Delphi's TMemo component? As far as I know VCL is not thread safe... 

 

Thank you.

 

Share this post


Link to post

I tried to set 

TPythonGUIInputOutput.DelayWrites = True 

I don't know what does it means but seems this resolve my issue (GUI output is working)

Maybe someone could clear this option, please?

 

P.S. I find related topic, usage of TPythonThread should be a solution but it still not prints in GUI output when  DelayWrites = False, maybe I miss something there...

 

Share this post


Link to post

Have you found the solution?

I seem to have found the solution.  I created the pythonengine and pythonmodule etc in a background thread

        procedure TQuoteThread._CreatePython(TheNil: TObject);
        begin
          RichEdit1 := TMemo.Create(nil);

          PythonGUIInputOutput := TPythonGUIInputOutput.Create(nil);
          PythonGUIInputOutput.UnicodeIO := true;
          PythonGUIInputOutput.Output := RichEdit1;

          modDBFireDac := TPythonModule.Create(nil);
          modDBFireDac.OnInitialization := modDBFireDacInitialization;
          modDBFireDac.ModuleName := 'DBFireDac';

          PyDelphiWrapper := TPyDelphiWrapper.Create(nil);

          PythonEngine := TPythonEngine.Create(nil); // 4.17
          PythonEngine.IO := PythonGUIInputOutput;

          modDBFireDac.Engine := PythonEngine;
          PyDelphiWrapper.Engine := PythonEngine;

          PythonEngine.LoadDll;

 

            pyObj := PyDelphiWrapper.Wrap(self); // 4.15
            with GetPythonEngine do
            begin
              // Define a new variable "T" in the DB module
              //4.37 modDBFireDac.SetVar('MainForm', pyObj);
              modDBFireDac.SetVar('BackgroundThread', pyObj); //4.37
              Py_XDecRef(pyObj);
              // Excecute the script
              ExecStrings(aLines);
            end;                                

        end;
                 

 

Then in the python script, it assigned the delphi thread to a python object

      delphithread = DBFireDac.BackgroundThread

When I need to pass output to Delphi, from within python script, I simply call the delphi thread method

   delphithread.AddLine(text)

In Delphi, the Delphi Thread method use TThread.ForceQueue to call a Form Method which add the output text to a TStringList

procedure TQuoteThread.AddLine(TheLine: String);
var
  aObj: TStringObj;
begin
  if (TheLine <> '') and Assigned(UIEvent_PrintLine) then
  begin
    TThread.ForceQueue(nil,
      procedure
      begin
        aObj := TStringObj.CreateWith(TheLine);
        UIEvent_PrintLine(aObj);
        FreeAndNil(aObj);
      end, 1);


  end;
end;

  • Thanks 1

Share this post


Link to post
On 8/22/2022 at 10:49 AM, DennisTW said:

Have you found the solution?

 

As I said before, this is solution for me:

TPythonGUIInputOutput.DelayWrites = True

Thank you for your help

 

 

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×