Jump to content
Registration disabled at the moment Read more... ×

pyscripter

Members
  • Content Count

    1026
  • Joined

  • Last visited

  • Days Won

    66

Everything posted by pyscripter

  1. Actually for this use case the TPythonModule is not needed. You can directly import the variables into the '__main__' module. e,g, procedure TForm1.Button1Click(Sender: TObject); var PyEngine: TPythonEngine; PyHeight: Integer; PyIO: TPythonGUIInputOutput; PyWidth: Integer; VarHeight: TPythonDelphiVar; VarWidth: TPythonDelphiVar; begin PyWidth := 80; PyHeight := 40; PyEngine := TPythonEngine.Create(nil); PyIO := TPythonGUIInputOutput.Create(nil); try PyIO.Output := Memo1; PyEngine.IO := PyIO; PyEngine.UseLastKnownVersion := True; PyEngine.AutoLoad := False; PyEngine.AutoUnload := False; try PyEngine.LoadDll; except on E: Exception do begin ShowMessage('Error at load Python: ' + E.Message); Exit; end; end; VarWidth := TPythonDelphiVar.Create(nil); VarWidth.Engine := PyEngine; VarWidth.Module := '__main__'; VarWidth.VarName := 'WIDTH'; VarWidth.Initialize; VarWidth.Value := PyWidth; VarHeight := TPythonDelphiVar.Create(nil); VarHeight.Engine := PyEngine; VarHeight.Module := '__main__'; VarHeight.VarName := 'HEIGHT'; VarHeight.Initialize; VarHeight.Value := PyHeight; var Source := ''' import math result = sum(i * i for i in range(1, 11)) print("Suma kwadratów od 1 do 10 to:", result) canvas = [[' ' for _ in range(WIDTH.Value)] for _ in range(HEIGHT.Value)] print(canvas) '''; PyEngine.ExecString(Utf8Encode(Source), '__main__'); finally VarWidth.Free; VarHeight.Free; PyIO.Free; PyEngine.Free; end; end;
  2. Here the following runs fine (without importing builtins): procedure TForm1.Button1Click(Sender: TObject); var PyEngine: TPythonEngine; PyHeight: Integer; PyIO: TPythonGUIInputOutput; PyModule: TPythonModule; PyWidth: Integer; VarHeight: TPythonDelphiVar; VarWidth: TPythonDelphiVar; begin PyWidth := 80; PyHeight := 40; PyEngine := TPythonEngine.Create(nil); PyModule := TPythonModule.Create(nil); PyIO := TPythonGUIInputOutput.Create(nil); try PyIO.Output := Memo1; PyEngine.IO := PyIO; PyEngine.UseLastKnownVersion := True; PyEngine.AutoLoad := False; PyEngine.AutoUnload := False; PyModule.Engine := PyEngine; PyModule.ModuleName := '__main__'; try PyEngine.LoadDll; except on E: Exception do begin ShowMessage('Error at load Python: ' + E.Message); Exit; end; end; PyModule.Initialize; //PyEngine.PyRun_SimpleString('import builtins; __builtins__ = builtins'); VarWidth := TPythonDelphiVar.Create(nil); VarWidth.Engine := PyEngine; VarWidth.Module := '__main__'; VarWidth.VarName := 'WIDTH'; VarWidth.Initialize; VarWidth.Value := PyWidth; VarHeight := TPythonDelphiVar.Create(nil); VarHeight.Engine := PyEngine; VarHeight.Module := '__main__'; VarHeight.VarName := 'HEIGHT'; VarHeight.Initialize; VarHeight.Value := PyHeight; var Source := ''' import math result = sum(i * i for i in range(1, 11)) print("Suma kwadratów od 1 do 10 to:", result) canvas = [[' ' for _ in range(WIDTH.Value)] for _ in range(HEIGHT.Value)] print(canvas) '''; PyEngine.ExecString(Utf8Encode(Source), '__main__'); finally VarWidth.Free; VarHeight.Free; PyIO.Free; PyModule.Free; PyEngine.Free; end; end; However you should not call the module '__main__', since by doing that you will be overriding the default python module with the same name. Call the module something else say my_module and then add to your python script: from my_module import WIDTH, HEIGHT
  3. The above should also be: HEIGHT.Value = 40 WIDTH.Value = 60 You should not need to import builtins. Not sure what the problem was.
  4. canvas = [[' ' for _ in range(WIDTH)] for _ in range(HEIGHT)] needs to be canvas = [[' ' for _ in range(WIDTH.Value)] for _ in range(HEIGHT.Value)]
  5. Does reversing the order help? VarWidth.Value := PyWidth; VarWidth.Initialize;
  6. I am confused. You are talking about your own python file (CustomClasses), but also something you installed via pip. For python to find your file it needs to be either on the python path or on the current directory. Run the following using P4D: import sys import os print(sys.path) print(os.getcwd()) print(sys.executable) and check the values of the path and the current directory. Also check which python version you are using.
  7. The code of TReader.ReadCollection is as follows: procedure TReader.ReadCollection(const Collection: TCollection); var Item: TPersistent; begin Collection.BeginUpdate; try if not EndOfList then Collection.Clear; while not EndOfList do begin if NextValue in [vaInt8, vaInt16, vaInt32] then ReadInteger; Item := Collection.Add; ReadListBegin; while not EndOfList do ReadProperty(Item); ReadListEnd; end; ReadListEnd; finally Collection.EndUpdate; end; end; It has been like this forever. My question is about the statement: if not EndOfList then Collection.Clear; It means that if you read an empty collection, the collection you are reading is not cleared or otherwise changed. The practical implication of this is that if you have a component that initializes a collection property with some items, there is no way to really clear it from the collection property inspector. Next time the form is loaded, either at run time or at design time, the collection will revert to the initialized state. Can you think of any reason TReader.ReadCollection does this? I think that if you read an empty collection, the collection property you are loading should be cleared. Should I report this as an issue? Also is there any workaround? I want a collection property to have a default state with some items created by the component constructor, but the users to be able to clear it at design time.
  8. pyscripter

    Python Output

    Multi-phase extension module initialization has been implemented. See Multi-phase module initialization implemented · pyscripter/python4delphi · Discussion #505 for details. What this means is that you can now create python extension modules with P4D that can be used with sub-interpreters including those created with the new concurrent.interpreters module of python 3.14.
  9. Another abandonware of Microsoft! It first sounded real good.
  10. Wow. Once, I had very high hopes for this technology, but it became another abandonware of Microsoft. Have you considered using python (pyscripter/python4delphi: Free components that wrap up Python into Delphi and Lazarus (FPC))? I guess though you were using JScript and you want to stick to JavaScript. For JavaScript there is also Microsoft's ChacraCore, which used to be the JavaScript engine of the old Edge browser. There is a good Delphi wrapper. See also the blog.
  11. @Vincent ParrettOut of curiosity, what are you using QuickJS for?
  12. pyscripter

    Interesting read about Sleep(0/1) and SwitshToThread

    By the way, TThread.Yield is the cross-platform way to call SwitchToThread.
  13. There are many components/libraries available for running processes and capturing their output. But, I got frustrated with their design and functionality, mostly for the following reasons: Fixation with and premature conversion to strings. Processes produce and consume bytes. Blocking reading of process output, resulting to inefficiencies (tight loops with Sleep, or separate threads for reading the output or providing input to the process) Incomplete features and/or over-bloated So, I have made my own pascal-process single unit library. Main features: Asynchronous reading of process output Separate stdout and stderr reading which can optionally be merged Ability to consume output as it is produced or else let it accumulate and read the final result Ability to provide input to the running process before or while the process is running. Ability to terminate the running process. Synchronous and asynchronous execution of processes. Interfaced-based facilitating memory management. MIT licence Usage: You do not need to install the library. Just download or clone the repo and add the source subdirectory to the Library path. Then add PascalProcess to your uses clause. If you just want to get the output of a process you can use the class functions of TPProcess. TPProcess = class(TInterfacedObject, IPProcess) class function Execute(const ACommandLine: string; const ACurrentDir: string = ''): TBytes; overload; class procedure Execute(const ACommandLine: string; const ACurrentDir: string; out Output, ErrOutput: TBytes) overload; end; This is an example: var Output: TBytes; begin Output := TPProcess.Execute('cmd /c echo Hi'); Writeln(TEncoding.ANSI.GetString(Output)); end; For more demanding cases you can use the IPProcess interface. Example: type TUtils = class class procedure OnRead(Sender: TObject; const Bytes: TBytes); end; class procedure TUtils.OnRead(Sender: TObject; const Bytes: TBytes); begin Writeln(TEncoding.ANSI.GetString(Bytes)); end; procedure Test2; // Processes ouput as it gets produced // The main thread terminates the process var Process: IPProcess; begin Process := TPProcess.Create('cmd /c dir c:\ /s'); Process.OnRead := TUtils.OnRead; WriteLn('Press Enter to start the process. Press Enter again to terminate'); ReadLn; Process.Execute; ReadLn; Process.Terminate; end; See here the definition of IPProcess. Limitations: Currently the library is Windows only. The intention is to support other platforms (help wanted).
  14. I set the pascal-process buffer to 4 *1024 for the comparison.
  15. Although, it does not look like it, the alertable wait does the same.
  16. @Kas Ob. There are many ways to skin a cat. The approach adopted in pascal-process uses asynchronous (overlapped) IO with alertable wait. So there are no tight loops with Sleep, or additional threads for reading. I think it is as efficient as it can get. I compared your code to pascal-process by using: 'cmd /v:on /c "set start=!time! && dir C:\Windows /s && set end=!time! && echo Start time: !start! && echo End time: !end!"'#13#10 Your code: Start time: 14:31:08.09 End time: 14:31:22.64 about 14 secs pascal-process Start time: 14:35:54.74 End time: 14:36:04.58 about 9 secs. To make sure disk caching did not play a role, I run your code again, with similar results: Start time: 15:01:58.56 End time: 15:02:14.17 About 15 secs. Of course one should not read much in a single benchmark. But, I do not see any reason your code is faster or otherwise better than the one used in pascal-process. Regarding AttachConsole do you happen to know, in which Delphi version it was first declared?
  17. @Kas Ob. This is an open-source project. You are welcome to create PRs, open issues, make suggestions etc.
  18. I have installed the Linux platform support and I am able to run simple Linux console applications targeting WSL. However, I cannot find the Posix source files, such as Posix.Base, Posix.SysTypes etc. What am I missing? I am using Delphi 12.3. I can see the files in my Delphi 11 installation.
  19. pyscripter

    Posix source files missing

    For some reason, I do not see the May Patch.
  20. @Dave Nottage Thanks for testing. I have updated the Readme with the corrected parameter list for OnRead. Regarding the conversion to string, the whole point of the library is that you get bytes. It is up to the user to use the bytes whichever way is appropriate. The console encoding may be not be Delphi's default encoding. In Linux it is most likely UTF8. On Windows one might use the GetConsoleOutputCP API to get the code page for the output. However even that is not reliable, For instance, on Windows, the scp command expects input and produces output in UTF8 encoding irrespective of the console encoding. The use of ANSI encoding on the project page was just an example. I agree thought that for the example TEncoding.Default is a better choice. So I have updated that as well.
  21. pascal-process is now multi-platform! So now there is a Delphi library to match fpc's TProcess. Desktop POSIX platforms (LINUX and MACOS) are now supported in addition to Windows. I have tested with LINUX. Since, I do not have a MACOS system available, I would appreciate some help in testing with MACOS.
  22. pyscripter

    Posix source files missing

    As mentioned I can compile code. Just the sources in the above path are missing.
  23. pyscripter

    Turbopower Visual Planit??

    For the record, TurboPower was a good company, but their components were commercial. They were open-sourced their products when the company shut-down their component business. However, they are products of the previous century and they show it. And incidentally, TurboPower was owned by a gambling business (a Casino or something).
  24. pyscripter

    Is it possible to implement floating/fully custom Dropdown Menus?

    Following on @Anders Melander suggestion you can find here a free implementation of his idea. The library also supports controls on menus and toolbars, is Vcl styles compatible and High-DPI aware. See some of the images here.
×