Jump to content

pyscripter

Members
  • Content Count

    775
  • Joined

  • Last visited

  • Days Won

    40

Posts posted by pyscripter


  1. 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? 


  2. 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 

     

    Quote

     

    How do I unload a Python module?

    Unloading a Python module is not possible in Python yet.

     

    Not sure what causes the delay.   

     

     


  3. 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.


  4. 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;

     


  5. 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)


     

    • Like 1

  6. 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;

     

     

    • Thanks 1

  7. 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.


  8. 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.

×