-
Content Count
775 -
Joined
-
Last visited
-
Days Won
40
Posts posted by pyscripter
-
-
The exit() function raises a SystemExit exception and if it is not handled it shuts down python. Don't use it in P4D scripts.
-
If you create an Engine client (e.g. TPythonDelphiVar TPythonModule) after the engine is initialized, you should call the client Initialize method. If the client is created before the engine is initialized, you should not call Initialize.
-
Could you post your minimal Delphi project in a zip file?
-
Destroying the engine and associated modules is normally instantaneous. Most of the demos do that. So that delay should be related to something "special" you are doing. Is python code running while you are doing that?
As an aside, why do you need to manually free the engine?
-
You are not supposed to destroy TPythonModules before engine destruction. They are automatically destroyed when the engine is destroyed. And it does not achieve the desired effect of removing it from python.
Python does not have a good mechanism for removing imported modules and this is not recommended in general. See for instance How do I really delete an imported module? (archive.org). Also from Reloading modules in Python - GeeksforGeeks
QuoteHow do I unload a Python module?
Unloading a Python module is not possible in Python yet.
Not sure what causes the delay.
-
9 hours ago, iqrf said:for key in spam.myPoint.ColumnA.Keys: #TypeError: 'Object' object is not iterable print(key😞
Use
for key in spam.myPoint.ColumnA.Keys.ToArray(): print(key)
It is possible to allow for a more natural iteration, but it would require to hand craft the TDictionary wrapper. See for instance how it is done in TPyDelphiStrings in WrapDelphiClasses.
-
1 hour ago, iqrf said:Many thanks once again.
Question about TPyPoint. From python it is always called CreateWith, you cannot call Create. Why is that? I solved it like this.
To write p = spam.Point() , I changed ii: to |ii
PyArg_ParseTupleAndKeywords(args, kwds, '|ii:CreatePoint',
@KeyPointerArray[0], @fx, @fy)You could allow for both Point() and Point(x, y) by modifying CreateWith
if PyArg_ParseTupleAndKeywords(args, kwds, '|ICreatePoint') then // no arguements else if PyArg_ParseTupleAndKeywords(args, kwds, 'ii|:CreatePoint', @fx, @fy) then // two integer arguements begin ... end;
-
To be able to create columns you need to also to customize the TColumn wrapper:
TColumnWrapper = class(TPyClassWrapper<TColumn>) constructor CreateWith(APythonType: TPythonType; args, kwds: PPyObject); override; end; constructor TColumnWrapper.CreateWith(APythonType: TPythonType; args, kwds: PPyObject); var W: integer; P: PPyObject; begin Create(APythonType); GetPythonEngine.PyArg_ParseTuple(args, 'iO:CreateColumn', @W, @P); DelphiObject := TColumn.Create; DelphiObject.Width := W; DelphiObject.Visible := GetPythonEngine.PyObject_IsTrue(P) = 1; end;
then register it in Form.Create
PyDelphiWrapper.RegisterDelphiWrapper(TColumnWrapper).Initialize; PyDelphiWrapper.RegisterDelphiWrapper(TPyClassWrapper<TDictionary<string, TColumn>>).Initialize;
Then the following code works:
from spam import myPoint, Column print(myPoint.ColumnA['Note'].Width) print(myPoint.ColumnA['Note'].Visible) new_column = Column(100, False) myPoint.ColumnA.Add('Note1', new_column) print(myPoint.ColumnA['Note1'].Width) print(myPoint.ColumnA['Note1'].Visible)
- 1
-
Assuming your register the dictionary as shown above the following works.
from spam import myPoint print(myPoint.ColumnA['Note'].Width) print(myPoint.ColumnA['Note'].Visible)
-
Please use the latest version from https://github.com/pyscripter/python4delphi/. Not the Getit version.
Here
PyDelphiWrapper.RegisterDelphiWrapper(TPyClassWrapper<TDictionary<string, TColumn>>).Initialize;
works.
You could also subclass TDictionary<string, TColumn>.
type
TColumnDict = class( TDictionary<string, TColumn>)
end;and in Form.Create
PyDelphiWrapper.RegisterDelphiWrapper(TPyClassWrapper<TColumnDict>).Initialize;
- 1
-
You need to register the TDictionary<String,TColumn> in Form.Create,
PyDelphiWrapper.RegisterDelphiWrapper(TPyClassWrapper<TDictionary<String,TColumn>>).Initialize;
Have not tested, Does it work?
-
See the record helpers in https://github.com/pyscripter/Pcre-Jit-Delphi/blob/master/Demos/benchmark.dpr and the methods SetAdditionalPCREOptions
- 1
-
I think this has to do with the default encoding of the pipe stdout. Python uses utf8, however since the script is run from a Delphi program it may inherit the encoding from the parent process. Just a guess.
-
uses VarPyth; ... var Res, S: string; PythonEngine1.ExecStrings(sl); Res := MainModule.Parser(S);
It would help to watch the tutorial videos and play with the Demos.
- 2
-
34 minutes ago, djxandytche said:create a singleton for the TPythonModule and TPyDelphiWrapper classes
A single TPythonModule and TPyDelphiWrapper should do.
34 minutes ago, djxandytche said:Wouldn't this cause problems with multi-threads since the DataSnap server can receive several requests at the same time?
Running python code in threads is quite complex. See PythonThreads · pyscripter/python4delphi Wiki (github.com) for details.
-
Why create/destroy/recreate the PythonModule and PythonWrapper instead of reusing them?
To avoid the finalization of the PythonEngine keep at least one client alive.
-
Do you have the appropriate python lib in your system?
eg.
See also the replies in Getting started with Ubuntu 18.04. Error Could not open DLL - Python4Delphi - Delphi-PRAXiS [en] (delphipraxis.net)
I would try first to run a console app and when this works then try an FMX app.
-
2 hours ago, JGMS said:The code line "if PyBytes_AsStringAndSize(presult, P, Len) < 0
I meant call CheckError before that.
-
Also have a look at Demo 35 to see how you transfer arrays and array-like objects from Python to Delphi using the buffer protocol.
-
Add some error checking after the call.
GetPythonEngine.CheckError;
What is the error you are getting?
It might help to post a minimal project.
-
4 minutes ago, PeaShooter_OMO said:How would copy and paste work?
It is explained in the link to CudaText I gave above.
-
All modern code editors have multi-select and multi-caret functionality (Visual Studio, VS-Code, Scintilla, Atom etc.). Also the freepascal CudaText. See CudaText - Free Pascal wiki for how it works. Very useful.
I am currently working to add this to SynEdit.
- 5
- 1
-
The sample code above uses VarPyth for high level access to python objects.
MainModule is custom variant wrapping the __main__ python module. Unless you provide optional parameters to ExecStrings, the code is executed in the context of the __main__ module.
- 1
- 1
-
How about?
var SL := TStringList.Crete; try SL.LoadFromFile('example.py'); PyEngine.ExecStrings(SL); var Res := MainModule.DoExample('input'); finally SL.Free; end;
- 1
Wrap TDictionary - TypeError: 'Object' object is not subscriptable
in Python4Delphi
Posted
TColumn.SetVisible is called, so inside that method Self is the TColumn object on which the method is called.