FranzB 0 Posted March 9, 2021 (edited) I have created the following simple application which should run on WINDOWS and LINUX using FMX framework and creating delphi4python components on run time . Why does this demo code not show any output result ? Most important line of code is this , or not ...? PythonInOut.OnSendUniData := PythonInputOutputSendUniData; I know this source https://blogs.embarcadero.com/learn-how-to-dynamically-create-and-destroy-python4delphi-components-with-a-delphi-windows-app/ but I intend to create a minimum code sequence type TForm1 = class(TForm) memoIn: TMemo; Splitter1: TSplitter; memoOut: TMemo; Panel1: TPanel; Button1: TButton; btnLoadScript: TButton; dlgOpen_pythonscript: TOpenDialog; btn_CreatePythonEnviroment: TButton; btn_FreePythonEnviroment: TButton; procedure Button1Click(Sender: TObject); procedure PythonInputOutputSendUniData(Sender: TObject; const Data: string); procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); procedure btnLoadScriptClick(Sender: TObject); procedure btn_CreatePythonEnviromentClick(Sender: TObject); procedure btn_FreePythonEnviromentClick(Sender: TObject); private { Private declarations } FOutputStream: TMemoryStream; FCriticalSection: TCriticalSection; public { Public declarations } PythonEngine: TPythonEngine; PythonInOut: TPythonInputOutput; end; var Form1: TForm1; implementation {$R *.fmx} procedure TForm1.btnLoadScriptClick(Sender: TObject); begin if dlgOpen_pythonscript.Execute then begin memoIn.Lines.Clear; memoIn.Lines.LoadFromFile(dlgOpen_pythonscript.FileName) end; end; /// /// did not drop components on a form , create components at run time ... /// procedure TForm1.btn_CreatePythonEnviromentClick(Sender: TObject); begin PythonEngine := TPythonEngine.Create(nil); PythonInOut := TPythonInputOutput.Create(nil); try PythonEngine.AutoLoad := true; {$IFDEF LINUX} PythonEngine.DllName := 'libpython3.6m.so'; PythonEngine.DllPath := '/usr/lib/x86_64-linux-gnu/'; {$ENDIF} {$IFDEF MSWINDOWS} PythonEngine.DllName := 'python310.dll'; PythonEngine.DllPath := ''; {$ENDIF} PythonEngine.AutoFinalize := true; PythonEngine.AutoLoad := true; PythonEngine.AutoUnload := true; PythonEngine.RedirectIO := true; PythonEngine.UseLastKnownVersion := true; PythonEngine.Loaddll; PythonEngine.IO := PythonInOut; PythonInOut.RawOutput := True; PythonInOut.OnSendUniData := PythonInputOutputSendUniData; except on E: Exception do writeln(E.ClassName, ': ', E.Message); end; end; procedure TForm1.Button1Click(Sender: TObject); begin PythonEngine.ExecString(UTF8Encode(memoIn.Text)); end; procedure TForm1.FormCreate(Sender: TObject); begin FOutputStream := TMemoryStream.Create; FCriticalSection := TCriticalSection.Create; end; procedure TForm1.FormDestroy(Sender: TObject); begin FOutputStream.Free; FCriticalSection.Free; end; procedure TForm1.PythonInputOutputSendUniData(Sender: TObject; const Data: string); { FMX TMemo is slow when adding many lines one by one. To avoid this we accumulate output and print it in one go. The critical section allows for multiple threads to print. If you use this code then set PythonInputOuput.RawOutput to True A simpler solution would be to set RawOuput to False and then do MemoOut.Lines.Add(Data); MemoOut.GoToTextEnd; This should be good enough if python does not produce a massive amount of output. } Var ScheduleWrite: Boolean; begin if Data = '' then Exit; FCriticalSection.Enter; try ScheduleWrite := FOutputStream.Size = 0; FOutputStream.Write(Data[1], Length(Data) * 2); if ScheduleWrite then TThread.ForceQueue(nil, procedure var WS: string; begin FCriticalSection.Enter; try if FOutputStream.Size > 0 then begin SetLength(WS, FOutputStream.Size div 2); FOutputStream.Position := 0; FOutputStream.Read(WS[1], Length(WS) * 2); FOutputStream.Size := 0; if (memoOut.Lines.Count > 0) and (memoOut.Lines[memoOut.Lines.Count - 1] <> '') then memoOut.Lines.Add(''); memoOut.Text := memoOut.Text + WS; memoOut.GoToTextEnd; end; finally FCriticalSection.Leave; end; end); finally FCriticalSection.Leave; end; end; end. Edited March 9, 2021 by FranzB Share this post Link to post
FranzB 0 Posted March 13, 2021 did a code rework and need to ask a different question Share this post Link to post