Difference between revisions of "Using Python in Lazarus on Windows/Linux"
Jwdietrich (talk | contribs) (→Intro) |
m (→Event handlers) |
||
Line 84: | Line 84: | ||
* 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 special folder for my app, to put Py modules, so I can import them). | ||
+ | <syntaxhighlight> | ||
procedure TfmMain.PythonEngineAfterInit(Sender: TObject); | procedure TfmMain.PythonEngineAfterInit(Sender: TObject); | ||
var | var | ||
Line 108: | Line 109: | ||
GetPythonEngine.ExecString(Str); | GetPythonEngine.ExecString(Str); | ||
end; | end; | ||
+ | </syntaxhighlight> | ||
* PythonInputOutput.OnSendData, OnSendUniData: | * PythonInputOutput.OnSendData, OnSendUniData: | ||
+ | <syntaxhighlight> | ||
procedure TfmMain.PythonInputOutput1SendData(Sender: TObject; | procedure TfmMain.PythonInputOutput1SendData(Sender: TObject; | ||
const Data: AnsiString); | const Data: AnsiString); | ||
Line 122: | Line 125: | ||
memoConsole.Lines.Add(Data); | memoConsole.Lines.Add(Data); | ||
end; | end; | ||
+ | </syntaxhighlight> | ||
* edConsole.OnKeyPress: | * edConsole.OnKeyPress: | ||
+ | <syntaxhighlight> | ||
procedure TfmMain.edConsoleKeyPress(Sender: TObject; var Key: char); | procedure TfmMain.edConsoleKeyPress(Sender: TObject; var Key: char); | ||
var | var | ||
Line 146: | Line 151: | ||
end; | end; | ||
end; | end; | ||
+ | </syntaxhighlight> | ||
* main form OnCreate: | * main form OnCreate: | ||
+ | <syntaxhighlight> | ||
procedure TfmMain.FormCreate(Sender: TObject); | procedure TfmMain.FormCreate(Sender: TObject); | ||
begin | begin | ||
Line 159: | Line 166: | ||
PythonEngine.LoadDll; | PythonEngine.LoadDll; | ||
end; | end; | ||
+ | </syntaxhighlight> | ||
[[Category:Python]] | [[Category:Python]] | ||
[[Category:Code]] | [[Category:Code]] |
Revision as of 01:43, 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
Work on Windows7 x64
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 special folder for my app, to put Py modules, so I can import them).
procedure TfmMain.PythonEngineAfterInit(Sender: TObject);
var
SDir, S1, S2, S3: string;
begin
{$ifdef windows}
SDir:= ExtractFilePath(Application.ExeName);
S1:= SDir + 'DLLs';
S2:= SDir + 'python33.zip';
S3:= SDir + 'Py';
Py_SetSysPath([S1, S2, S3]);
{$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;