Difference between revisions of "Using Python in Lazarus on Windows/Linux"
m (→Intro) |
(→Result) |
||
Line 6: | Line 6: | ||
= Result = | = Result = | ||
− | + | Github repo: | |
+ | https://github.com/Alexey-T/Python-for-Lazarus | ||
− | + | Shot on Ubuntu 14.04 x64: | |
− | |||
− | |||
− | |||
[[File:Python app Linux.png]] | [[File:Python app Linux.png]] | ||
− | + | Shot on Windows 7 x64: | |
[[File:Python app Windows.png]] | [[File:Python app Windows.png]] | ||
− | + | Shot on Mac OS 10.8: | |
[[File:Python app MacOS.png]] | [[File:Python app MacOS.png]] |
Revision as of 04:44, 20 April 2015
Intro
I need to make app, cross platform, Win/Linux/Mac, which embeds Python engine. I tried Python4Delphi, it doesn't compile and work on Linux x64 and Mac. App must use: portable Python on Win, system Python on Linux, Python installer on Mac.
Result
Github repo: https://github.com/Alexey-T/Python-for-Lazarus
Shot on Ubuntu 14.04 x64:
Shot on Windows 7 x64:
Shot on Mac OS 10.8:
P4D fork
You need modified P4D package, see link to Github above. Compile and install the package. You must see "Python" tab appeared in component pallette. What is changed:
- deleted all refs to units "..Delphi..", seems units aren't needed for Lazarus apps.
- modifications to PythonEngine.pas, see lines with "//AT".
- added support for Mac for ex. by replacing "ifdef linux" with "ifdef unix".
Files on Windows
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>
Files on MacOS
OSX 10.8 doesn't have Python. User needs to install official Py 3.4 pack.
Full path to library must be set in code, I could not load it w/out path. (Maybe I can read some env-var, I didn't try.)
Code
Form
Put on form:
- TPythonEngine
- TPythonInputOutput
- TCombobox (edConsole)
- TMemo (memoConsole)
Properties 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" for Win (remember, we use portable py for Win).
procedure TfmMain.PythonEngineAfterInit(Sender: TObject);
var
dir: string;
begin
{$ifdef windows}
dir:= ExtractFilePath(Application.ExeName);
Py_SetSysPath([
dir + 'DLLs',
dir + 'python33.zip'
]);
{$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:
const
cPyLibraryWindows = 'python33.dll';
cPyLibraryLinux = 'libpython3.4m.so.1.0';
cPyLibraryMac = '/Library/Frameworks/Python.framework/Versions/3.4/lib/libpython3.4.dylib';
procedure TfmMain.FormCreate(Sender: TObject);
var
S: string;
begin
S:=
{$ifdef windows} cPyLibraryWindows {$endif}
{$ifdef linux} cPyLibraryLinux {$endif}
{$ifdef darwin} cPyLibraryMac {$endif} ;
PythonEngine.DllPath:= ExtractFileDir(S);
PythonEngine.DllName:= ExtractFileName(S);
PythonEngine.LoadDll;
end;