Difference between revisions of "Using Python in Lazarus on Windows/Linux"

From Free Pascal wiki
Jump to navigationJump to search
Line 82: Line 82:
 
== Event handlers ==
 
== Event handlers ==
  
* PythonEngine.OnAfterInit: must set "sys.path". Only for Windows. I add paths: dir+'DLLs', dir+'python33.zip', dir+'Py' ("Py" is special folder for my app, to put Py modules, so I can import them).
+
* PythonEngine.OnAfterInit: must set "sys.path". Only for Windows. I add paths: dir+'DLLs', dir+'python33.zip', dir+'Py' ("Py" is a special folder for my app, to put modules).
  
 
<syntaxhighlight>
 
<syntaxhighlight>
  procedure TfmMain.PythonEngineAfterInit(Sender: TObject);
+
procedure TfmMain.PythonEngineAfterInit(Sender: TObject);
  var
+
var
    SDir, S1, S2, S3: string;
+
  dir: string;
  begin
+
begin
    {$ifdef windows}
+
  {$ifdef windows}
    SDir:= ExtractFilePath(Application.ExeName);
+
  dir:= ExtractFilePath(Application.ExeName);
     S1:= SDir + 'DLLs';
+
  Py_SetSysPath([
     S2:= SDir + 'python33.zip';
+
     dir + 'DLLs',
     S3:= SDir + 'Py';
+
     dir + 'python33.zip',
     Py_SetSysPath([S1, S2, S3]);
+
     dir + 'Py'
    {$endif}
+
     ]);
  end;
+
  {$endif}
 +
end;
  
  procedure Py_SetSysPath(const Dirs: array of string);
+
procedure Py_SetSysPath(const Dirs: array of string);
  var
+
var
    Str: string;
+
  Str: string;
    i: Integer;
+
  i: Integer;
  begin
+
begin
    Str:= '';
+
  Str:= '';
    for i:= 0 to Length(Dirs)-1 do
+
  for i:= 0 to Length(Dirs)-1 do
      Str:= Str + 'r"' + Dirs[i] + '"' + ',';
+
    Str:= Str + 'r"' + Dirs[i] + '"' + ',';
    Str:= Format('sys.path = [%s]', [Str]);
+
  Str:= Format('sys.path = [%s]', [Str]);
    GetPythonEngine.ExecString(Str);
+
  GetPythonEngine.ExecString(Str);
  end;
+
end;
 
</syntaxhighlight>
 
</syntaxhighlight>
  
Line 114: Line 115:
  
 
<syntaxhighlight>
 
<syntaxhighlight>
  procedure TfmMain.PythonInputOutput1SendData(Sender: TObject;
+
procedure TfmMain.PythonInputOutput1SendData(Sender: TObject;
    const Data: AnsiString);
+
  const Data: AnsiString);
  begin
+
begin
    memoConsole.Lines.Add(Data);
+
  memoConsole.Lines.Add(Data);
  end;
+
end;
  
  procedure TfmMain.PythonInputOutput1SendUniData(Sender: TObject;
+
procedure TfmMain.PythonInputOutput1SendUniData(Sender: TObject;
    const Data: UnicodeString);
+
  const Data: UnicodeString);
  begin
+
begin
    memoConsole.Lines.Add(Data);
+
  memoConsole.Lines.Add(Data);
  end;
+
end;
 
</syntaxhighlight>
 
</syntaxhighlight>
  
Line 130: Line 131:
  
 
<syntaxhighlight>
 
<syntaxhighlight>
  procedure TfmMain.edConsoleKeyPress(Sender: TObject; var Key: char);
+
procedure TfmMain.edConsoleKeyPress(Sender: TObject; var Key: char);
  var
+
var
    Str: string;
+
  Str: string;
 +
begin
 +
  if Key=#13 then
 
   begin
 
   begin
     if Key=#13 then
+
     Str:= edConsole.Text;
    begin
+
 
      Str:= edConsole.Text;
+
    //support entering "=some cmd"
 
+
    if (Str<>'') and (Str[1]='=') then
      //support entering "=some cmd"
+
      Str:= 'print('+Copy(Str, 2, MaxInt) + ')';
      if (Str<>'') and (Str[1]='=') then
+
 
        Str:= 'print('+Copy(Str, 2, MaxInt) + ')';
+
    memoConsole.Lines.Add('>>> '+Str);
 
+
    edConsole.Text:= '';
      memoConsole.Lines.Add('>>> '+Str);
+
    edConsole.Items.Insert(0, Str);
      edConsole.Text:= '';
+
    try
      edConsole.Items.Insert(0, Str);
+
      GetPythonEngine.ExecString(Str);
      try
+
    except
        GetPythonEngine.ExecString(Str);
 
      except
 
      end;
 
 
     end;
 
     end;
 
   end;
 
   end;
 +
end;
 
</syntaxhighlight>
 
</syntaxhighlight>
  
Line 156: Line 157:
  
 
<syntaxhighlight>
 
<syntaxhighlight>
  procedure TfmMain.FormCreate(Sender: TObject);
+
procedure TfmMain.FormCreate(Sender: TObject);
  begin
+
begin
    {$ifdef windows}
+
  {$ifdef windows}
    PythonEngine.DllName:= 'python33.dll';
+
  PythonEngine.DllName:= 'python33.dll';
    {$endif}
+
  {$endif}
    {$ifdef linux}
+
  {$ifdef linux}
    PythonEngine.DllName:= 'libpython3.4m.so.1.0';
+
  PythonEngine.DllName:= 'libpython3.4m.so.1.0';
    {$endif}
+
  {$endif}
    PythonEngine.LoadDll;
+
  PythonEngine.LoadDll;
  end;
+
end;
 
</syntaxhighlight>
 
</syntaxhighlight>
  
 
[[Category:Python]]
 
[[Category:Python]]
 
[[Category:Code]]
 
[[Category:Code]]

Revision as of 02:23, 9 February 2015

Intro

I need to make app, cross platform, Win/Linux, which embeds Python engine. I tried Python4Delphi, but it doesn't compile and work on Linux x64. Same app must run on Win and Linux, must use portable Python 3 on Win and system Python 3 on Linux.

Result

Links

Work on Ubuntu 14.04 x64

Python app Linux.png

Work on Windows7 x64

Python app Windows.png

Modify P4D

Package "p4dlaz.lpk": delete all refs to units "...Delphi...". (Maybe units aren't needed for Lazarus apps.) Make modifications to PythonEngine.pas, see lines with "//AT". Compile and use package. You must see "Python" tab appeared in component pallette.

App

Files needed

On Windows you need to copy files to app folder. From "Sublime Text 3" installation for win, take Python files and copy them to app folder:

  • python33.dll
  • msvcr100.dll
  • python33.zip
  • .pyd files to folder DLLs

Manifest on Windows: "appname.exe.manifest":

 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
 <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
   <noInheritable/>
   <assemblyIdentity
       type="win32"
       name="DelphiApplication"
       version="1.0.0.0" 
       processorArchitecture="*"/>
   <dependency>
     <dependentAssembly>
       <assemblyIdentity type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*' />
     </dependentAssembly>
   </dependency>
   <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
     <security>
       <requestedPrivileges>
         <requestedExecutionLevel level='asInvoker' uiAccess='false' />
       </requestedPrivileges>
     </security>
   </trustInfo>
 </assembly>

App form

Put on form:

  • TPythonEngine
  • TPythonInputOutput
  • TCombobox (edConsole)
  • TMemo (memoConsole)

Props of PythonEngine:

  • AutoLoad=False
  • DllName empty
  • DllPath empty
  • FatalAbort=False
  • InitScript="import sys; print('Python', sys.version)"
  • IO=PythonInputOutput1
  • PyFlags=[pfIgnoreEnvironmentFlag]
  • UseLastKnownVersion=False

Event handlers

  • PythonEngine.OnAfterInit: must set "sys.path". Only for Windows. I add paths: dir+'DLLs', dir+'python33.zip', dir+'Py' ("Py" is a special folder for my app, to put modules).
procedure TfmMain.PythonEngineAfterInit(Sender: TObject);
var
  dir: string;
begin
  {$ifdef windows}
  dir:= ExtractFilePath(Application.ExeName);
  Py_SetSysPath([
    dir + 'DLLs',
    dir + 'python33.zip',
    dir + 'Py'
    ]);
  {$endif}
end;

procedure Py_SetSysPath(const Dirs: array of string);
var
  Str: string;
  i: Integer;
begin
  Str:= '';
  for i:= 0 to Length(Dirs)-1 do
    Str:= Str + 'r"' + Dirs[i] + '"' + ',';
  Str:= Format('sys.path = [%s]', [Str]);
  GetPythonEngine.ExecString(Str);
end;
  • PythonInputOutput.OnSendData, OnSendUniData:
procedure TfmMain.PythonInputOutput1SendData(Sender: TObject;
  const Data: AnsiString);
begin
  memoConsole.Lines.Add(Data);
end;

procedure TfmMain.PythonInputOutput1SendUniData(Sender: TObject;
  const Data: UnicodeString);
begin
  memoConsole.Lines.Add(Data);
end;
  • edConsole.OnKeyPress:
procedure TfmMain.edConsoleKeyPress(Sender: TObject; var Key: char);
var
  Str: string;
begin
  if Key=#13 then
  begin
    Str:= edConsole.Text;

    //support entering "=some cmd"
    if (Str<>'') and (Str[1]='=') then
      Str:= 'print('+Copy(Str, 2, MaxInt) + ')';

    memoConsole.Lines.Add('>>> '+Str);
    edConsole.Text:= '';
    edConsole.Items.Insert(0, Str);
    try
      GetPythonEngine.ExecString(Str);
    except
    end;
  end;
end;
  • main form OnCreate:
procedure TfmMain.FormCreate(Sender: TObject);
begin
  {$ifdef windows}
  PythonEngine.DllName:= 'python33.dll';
  {$endif}
  {$ifdef linux}
  PythonEngine.DllName:= 'libpython3.4m.so.1.0';
  {$endif}
  PythonEngine.LoadDll;
end;