Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Lazarus Pascal Discussion :

TProcess : redirection d'un flux Python vers un TMemo


Sujet :

Lazarus Pascal

  1. #1
    Rédacteur

    TProcess : redirection d'un flux Python vers un TMemo
    Bonjour .

    Je voudrais rediriger le flux de sortie d'un script Python vers un TMemo.

    J'utilise le script Python suivant :
    Code python :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    #!/usr/bin/env python
    # coding: utf8
     
    import time
    print('Compte à rebours:')
    time.sleep(1.0)
    i = 1
    while i < 11:
         print(11 - i)
         i += 1
         time.sleep(1.0)
    print('C''est parti:')


    Si je le lance dans la console, ça me donne :


    En utilisant le code Lazarus suivant :
    Code pascal :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
     
    procedure TForm1.Button1Click(Sender: TObject);
    var
      Processus: TProcess;
    begin
      try
        Processus := TProcess.Create(nil);
        Processus.Executable:= 'python';
        Processus.Parameters.Add('test.py');
        Processus.Options := Processus.Options + [poUsePipes];
        Processus.Execute;
        Memo1.Lines.LoadFromStream(Processus.output);
        finally
        Processus.Free;
      end;
    end;


    j'obtiens ceci :


    Apparemment tout va bien sauf que dans la console, l'affichage suit bien le script, à savoir :
    • affichage de "Compte à rebours :" ;
    • pause de 1 seconde ;
    • affichage de "10" ;
    • pause de 1 seconde
    • ... ;
    • affichage de "C'est parti :".


    alors qu'en ce qui concerne le TMemo, le tout s'affiche en bloc après une attente correspondant à la somme des pauses.

    Y a-t-il un moyen d'obtenir sur le TMemo le même affichage "dynamique" que sur la console ?

    Merci d'avance,
    naute

  2. #2
    Expert confirmé
    hello,
    pour faire des échanges entre lazarus et du python il y a mieux qu'utiliser un Tprocess : il y a le paquet pythonForlazarus voir ici . PythonForLazarus est présent dans le gestionnaire de paquets en ligne.

    Ami calmant, J.P
    Jurassic computer : Sinclair ZX81 - Zilog Z80A à 3,25 MHz - RAM 1 Ko - ROM 8 Ko

  3. #3
    Rédacteur

    Bonjour jurassic pork .

    Merci pour ta réponse .

    Dans mes recherches sur TProcess, je suis déjà tombé sur le fil dont tu parles, mais mon but n'est pas spécifiquement faire des échanges entre Lazarus et Python. Les scripts que j'utilise n'attendent pas une saisie utilisateur. Ils n'ont besoin que de la ligne de commande.

    Je veux simplement lancer sous Lazarus des scripts python (ça c'est simple), et à l'occasion des commandes shell, et utiliser un TMemo comme stdOut à la place de la console, autant pour les sorties normales que pour les messages d'erreur, et que le rendu soit le même qu'avec la console, c'est à dire ne pas attendre que le programme soit terminé pour afficher les résultats intermédiaires. Est-ce que pythonForlazarus fait ça ?

    J'ai déjà installé le paquet CmdLine (qui est dans le dépot local comme pythonFoLazarus), pour voir, mais l'absence de doc, comme pour beaucoup de paquets, le rend inutilisable (ce n'est pas une critique, mais c'est dommage de faire un super boulot qui s'avérera difficile, voire impossible, à exploiter en raison d'un manque de documentation).

    Amicalement,
    naute

  4. #4
    Modérateur

    Bonjour,
    Y aurait-il une piste ici, à l'alinéa "Reading large output" en adaptant la boucle de lecture ?
    Delphi 5 Pro - Delphi 10.3.2 Rio Community Edition - CodeTyphon 6.90 sous Windows 10 ; CT 6.40 sous Ubuntu 18.04 (VM)
    . Ignorer la FAQ Delphi et les Cours et Tutoriels Delphi nuit gravement à notre code !

  5. #5
    Expert confirmé
    hello,
    il y a mieux que TProcess :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    TprocessEx includes Real time output management.


    voir ici

    et PythonforLazarus affiche aussi les print en temps réel :



    Ami calmant, J.P
    Jurassic computer : Sinclair ZX81 - Zilog Z80A à 3,25 MHz - RAM 1 Ko - ROM 8 Ko

  6. #6
    Rédacteur/Modérateur

    Bonjour !

    Dans les exemples de Lazarus, il y a une démo qui permet de faire ce genre de chose. Elle permet même de faire plus, puisqu'on peut envoyer des lignes au processus en cours d'exécution.

    https://sourceforge.net/p/lazarus-cc...momainform.pas

  7. #7
    Membre expert
    Salut Naute,

    Un des problèmes c'est ton script python qui utilise Print et qui est "bloquant"

    Essayes comme ceci :

    Code python :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
     
    #!/usr/bin/env python
    # coding: utf8
     
    import sys, time
     
    def ConsolePrint(msg):
          sys.stdout.write(msg)
          sys.stdout.flush()
     
    print('Compte à rebours:')
    time.sleep(1.0)
    i = 1
    while i < 11:
         j = 11 - i
         mymsg = str(j) + "\n"
         ConsolePrint(mymsg)
         i += 1
         time.sleep(0.5)
    print('C''est parti:')


    Deuxièmement utilises plutôt l'unité "ProcessUtil" de cette discussion et de FPCUpDeluxe

    (Notes : Tu peux commenter les lignes de 274 à 277 pour avoir un affichage bien clean)

    Ensuite procèdes comme ceci :

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    unit Unit1;
     
    {$mode objfpc}{$H+}
     
    interface
     
    uses
      Classes, SysUtils, Process, Forms, Controls, Graphics, Dialogs, StdCtrls,
      ProcessUtils;
     
    type
     
      { TForm1 }
     
      TForm1 = class(TForm)
        mmoConsole: TMemo;
        Button1: TButton;
     
        procedure Button1Click(Sender: TObject);
      private
        FProcessEx : TProcessEx;
        procedure ProcessExOutput(Sender:TProcessEx; output:string);
        procedure ProcessExError(Sender:TProcessEx; {%H-}IsException:boolean);
      public
     
      end;
     
    var
      Form1: TForm1;
     
    implementation
     
    {$R *.lfm}
     
    uses LazUTF8;
     
    { TForm1 }
     
    procedure TForm1.Button1Click(Sender: TObject);
    begin
      try
       Screen.Cursor := crHourGlass;
       FProcessEx := TProcessEx.Create(Self);
       FProcessEx.Options :=  FProcessEx.Options + [poUsePipes];
       FProcessEx.Executable := 'python';
       FProcessEx.Parameters.Add('test2.py');
       FProcessEx.OnOutputM := @ProcessExOutput;
       FProcessEx.OnErrorM := @ProcessExError;
       FProcessEx.PipeBufferSize := 10 * 1024;
     
       FProcessEx.Execute();
     
       While FProcessEx.Running do
       begin
         If FProcessEx.Output.NumBytesAvailable > 0 Then
         begin
           Application.ProcessMessages;
         end;
         If FProcessEx.StdErr.NumBytesAvailable > 0 Then
         begin
           Application.ProcessMessages;
         end;
       end;
     
      finally
       FreeAndNil(FProcessEx);
       Screen.Cursor := crDefault;
      end;
    end;
     
    procedure TForm1.ProcessExError(Sender: TProcessEx; IsException: boolean);
    begin
       mmoConsole.Lines.Append('Erreur ! ' + Sender.ExceptionInfo);
    end;
     
    procedure TForm1.ProcessExOutput(Sender: TProcessEx; output : String);
    begin
      {$IFDEF WINDOWS}
      mmoConsole.Lines.Text :=  mmoConsole.Lines.Text + WinCPToUTF8(output);
      {$ELSE}
      mmoConsole.Lines.Text :=  mmoConsole.Lines.Text + output;
      {$ENDIF}
     
      // pour scroll automatique
      mmoConsole.SelStart := Length(mmoConsole.Lines.Text)-1;
      mmoConsole.SelLength:=0;
     
    end;
     
    end.


    Résultat sous Windows


    A+

    Jérôme

    EDIT : @jurassic pork : Le temps que je ponde l'exemple, nos message se sont croisés
    • "L'Homme devrait mettre autant d'ardeur à simplifier sa vie qu'il met à la compliquer" - Henri Bergson
    • "Bien des livres auraient été plus clairs s'ils n'avaient pas voulu être si clairs" - Emmanuel Kant
    • "La simplicité est la sophistication suprême" - Léonard De Vinci
    • "Ce qui est facile à comprendre ou à faire pour toi, ne l'est pas forcément pour l'autre." - Mon pèrei

    Mes projets sur Github - Blog - Site DVP

  8. #8
    Membre expert
    Y'a eu de la mise à jour du coté de FPCUpDeluxe je te met l'unié "ProcessUtils" en attachement

    A+

    Jérôme
    • "L'Homme devrait mettre autant d'ardeur à simplifier sa vie qu'il met à la compliquer" - Henri Bergson
    • "Bien des livres auraient été plus clairs s'ils n'avaient pas voulu être si clairs" - Emmanuel Kant
    • "La simplicité est la sophistication suprême" - Léonard De Vinci
    • "Ce qui est facile à comprendre ou à faire pour toi, ne l'est pas forcément pour l'autre." - Mon pèrei

    Mes projets sur Github - Blog - Site DVP

  9. #9
    Rédacteur/Modérateur

    Bien vu Jérôme le coup du "flush" ! J'étais en train de me demander pourquoi ma démo ne fonctionnait pas. Je n'avais pas pensé à cette histoire de "flush" (alors que c'est un problème bien connu pour les moteurs d'échecs).

  10. #10
    Membre expert
    Citation Envoyé par Roland Chastain Voir le message
    Bien vu Jérôme le coup du "flush" ! J'étais en train de me demander pourquoi ma démo ne fonctionnait pas. Je n'avais pas pensé à cette histoire de "flush" (alors que c'est un problème bien connu pour les moteurs d'échecs).
    Merci

    du coup, on peut virer cette partie :

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
       While FProcessEx.Running do
       begin
         If FProcessEx.Output.NumBytesAvailable > 0 Then
         begin
           Application.ProcessMessages;
         end;
         If FProcessEx.StdErr.NumBytesAvailable > 0 Then
         begin
           Application.ProcessMessages;
         end;
       end;


    Je ne sais pas trop pourquoi, lors, de mes essais, lorsque je l'avais supprimé, cela ne fonctionnait plus, et la miracle ; sans ; tout (re)marche
    • "L'Homme devrait mettre autant d'ardeur à simplifier sa vie qu'il met à la compliquer" - Henri Bergson
    • "Bien des livres auraient été plus clairs s'ils n'avaient pas voulu être si clairs" - Emmanuel Kant
    • "La simplicité est la sophistication suprême" - Léonard De Vinci
    • "Ce qui est facile à comprendre ou à faire pour toi, ne l'est pas forcément pour l'autre." - Mon pèrei

    Mes projets sur Github - Blog - Site DVP

  11. #11
    Rédacteur

    D'abord, bonjour et merci à tous .

    Citation Envoyé par tourlourou Voir le message
    Y aurait-il une piste ici, à l'alinéa "Reading large output" en adaptant la boucle de lecture ?
    C'est une des premières pages que j'ai consulté pendant mes recherches, et d'ailleurs, mon exemple est une adaptation d'un des codes qui s'y trouvent. Peut-être que le code dont tu parles solutionnerait mon problème, mais je n'ai pas trouvé comment l'adapter à mon cas.

    Citation Envoyé par Roland Chastain Voir le message
    Dans les exemples de Lazarus, il y a une démo qui permet de faire ce genre de chose.
    C'est une piste intéressante si je décide de rester sur TProcess. Petit inconvénient, ce code utilise CommandLine qui est considéré comme obsolète, mais ce n'est pas forcément un obstacle.

    Citation Envoyé par BeanzMaster Voir le message
    Un des problèmes c'est ton script python qui utilise Print et qui est "bloquant"
    Oui, mais il a beau être bloquant, ça fonctionne quand même dans la console . Et il est impératif que l'affichage dans le TMemo fonctionne pour tout script Python valide.

    Citation Envoyé par BeanzMaster Voir le message
    Y'a du de la mise à jour du coté de FPCUpDeluxe je te met l'unié "ProcessUtils" en attachement
    Merci pour l'unité en pièce jointe Jérôme .

    @jurassic pork et @BeanzMaster
    Je pense que je vais m'intéresser sérieusement à l'unité ProcessUtil et à TProcessEx. Par contre, je suppose qu'il n'y a pas de documentation. Ou peut-être ?

    Je vous tiens au courant de mes avancées,
    amicalement,
    Hervé

  12. #12
    Membre expert
    Salut Hervé
    Citation Envoyé par naute Voir le message


    Oui, mais il a beau être bloquant, ça fonctionne quand même dans la console . Et il est impératif que l'affichage dans le TMemo fonctionne pour tout script Python valide.

    Oui mais sans le "flush" c'est mort. (pour le moment) Et à moins qu'il y ai une autre façon de faire en Python. Mais là je suis pas assez calé avec ce langage.
    Pis si tu veux afficher la sortie dans un memo quel est l’intérêt dans ce cas de vouloir afficher les lignes une à une. Surtout si le terminal n'est pas visible ?
    Après si tes scripts proviennent de diverses sources, il te faudra les adapter et avoir 2 versions. La normale et celle pour ton application.

    Citation Envoyé par naute Voir le message

    Merci pour l'unité en pièce jointe Jérôme .

    @jurassic pork et @BeanzMaster
    Je pense que je vais m'intéresser sérieusement à l'unité ProcessUtil et à TProcessEx. Par contre, je suppose qu'il n'y a pas de documentation. Ou peut-être ?

    Je vous tiens au courant de mes avancées,
    amicalement,
    Hervé
    Pas de soucis Franchement le TProcessEx est super utile, je trouve. Et pour ce qui est de la doc, ben c'est tout pareil que le TProcess, sauf que tu as les événements "OnOutputM/ OnOuput" et "OnErriom / OnError" pour capter les messages au fur et à mesure, provenant de la console. Plus quelques propriétés supplémentaires spécifiques, mais rien de bien méchant.

    A+

    Jérôme
    • "L'Homme devrait mettre autant d'ardeur à simplifier sa vie qu'il met à la compliquer" - Henri Bergson
    • "Bien des livres auraient été plus clairs s'ils n'avaient pas voulu être si clairs" - Emmanuel Kant
    • "La simplicité est la sophistication suprême" - Léonard De Vinci
    • "Ce qui est facile à comprendre ou à faire pour toi, ne l'est pas forcément pour l'autre." - Mon pèrei

    Mes projets sur Github - Blog - Site DVP

  13. #13
    Rédacteur/Modérateur

    Citation Envoyé par naute Voir le message

    C'est une piste intéressante si je décide de rester sur TProcess. Petit inconvénient, ce code utilise CommandLine qui est considéré comme obsolète, mais ce n'est pas forcément un obstacle.
    Concernant CommandLine, la modification est vite faite. D'ailleurs voici l'adaptation que je viens de faire de la démo en question.

    Deux choses à noter. 1° La dernière ligne ne s'affiche pas toujours. La démo est conçue pour un processus qui ne s'arrête pas tant qu'on le ne lui dit pas de s'arrêter. Là tout de suite je ne vois pas comment régler ce problème.

    2° La redirection de l'erreur ne semble pas fonctionner, malgré l'option poStderrToOutput. Je m'en suis aperçu parce que le "à" (avec un accent) dans le script faisait échouer l'exécution, et que je ne voyais pas le message d'erreur. Mais peut-être que c'est tout simplement parce que la dernière ligne ne s'affiche pas.

  14. #14
    Rédacteur/Modérateur

    Citation Envoyé par Roland Chastain Voir le message
    Deux choses à noter. 1° La dernière ligne ne s'affiche pas toujours. La démo est conçue pour un processus qui ne s'arrête pas tant qu'on le ne lui dit pas de s'arrêter. Là tout de suite je ne vois pas comment régler ce problème.

    2° La redirection de l'erreur ne semble pas fonctionner, malgré l'option poStderrToOutput. Je m'en suis aperçu parce que le "à" (avec un accent) dans le script faisait échouer l'exécution, et que je ne voyais pas le message d'erreur. Mais peut-être que c'est tout simplement parce que la dernière ligne ne s'affiche pas.
    J'ai trouvé une solution. Supprimer la condition if AProcess.Running then (dans la procédure DoStuffForProcess).

    Attention ! Du coup, il faut démarrer le timer seulement après le lancement du processus, autrement il y a une violation d'accès (qui ne se produit pas après après le processus s'est arrêté, je ne sais pas pourquoi).

    Une fois cette modification faite, les messages d'erreurs éventuels s'affichent bien.

  15. #15
    Rédacteur

    J'ai donc testé les trois codes , ceux de Jérôme et de Jurassic Pork qui sont assez proches et qui utilisent TProcessEx, et celui de Roland qui utilise TProcess : les rendus sont similaire, à savoir que leur comportement par rapport au script Python est le même, et qu'en demandant de charger un fichier qui n'existe pas dans le chemin, j'ai le message d'erreur correspondant.

    L'inconvénient, c'est qu'ils ont également le même comportement quand je laisse "python" (en réalité python3 mais ça revient au même) comme exécutable mais que je ne passe pas de paramètre : il ne se passe rien au niveau affichage et le programme "boucle", alors qu'il devrait afficher :


    De même, quand je lance "python3 -h" (en respectant la syntaxe bien sûr), l'aide ne s'affiche pas et ça plante.

    Comment faire pour résoudre ce type de problème ?

    Bon, il est temps d'y aller, bonne nuit à tous ,
    amicalement,
    Hervé

  16. #16
    Membre expert
    Citation Envoyé par naute Voir le message

    L'inconvénient, c'est qu'ils ont également le même comportement quand je laisse "python" (en réalité python3 mais ça revient au même) comme exécutable mais que je ne passe pas de paramètre : il ne se passe rien au niveau affichage et le programme "boucle", alors qu'il devrait afficher :


    Salut, dans ce cas présent ce n'est pas possible, (cela me rappel une discussion avec sqlite3)
    Ici Python fait une "redirection" et attend que l'utilisateur rentre des commandes

    Roland avait eu un problème similaire et sa solution ne fonctionne que sous Windows

    Sinon tu peux te tourner vers un émulateur de terminal, mais marchera, cette fois-ci que sous linux si je ne me trompe pas.

    Citation Envoyé par naute Voir le message

    De même, quand je lance "python3 -h" (en respectant la syntaxe bien sûr), l'aide ne s'affiche pas et ça plante.
    Chez moi sous Windows avec TProcessEx, ça fonctionne

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
       FProcessEx := TProcessEx.Create(Self);
       FProcessEx.Options :=  FProcessEx.Options + [poUsePipes];
       FProcessEx.Executable := 'python';
       FProcessEx.Parameters.Add('-h');
       FProcessEx.OnOutputM := @ProcessExOutput;
       FProcessEx.OnErrorM := @ProcessExError;
       FProcessEx.PipeBufferSize := 10 * 1024;
       FProcessEx.Execute();




    A+

    Jérôme
    • "L'Homme devrait mettre autant d'ardeur à simplifier sa vie qu'il met à la compliquer" - Henri Bergson
    • "Bien des livres auraient été plus clairs s'ils n'avaient pas voulu être si clairs" - Emmanuel Kant
    • "La simplicité est la sophistication suprême" - Léonard De Vinci
    • "Ce qui est facile à comprendre ou à faire pour toi, ne l'est pas forcément pour l'autre." - Mon pèrei

    Mes projets sur Github - Blog - Site DVP

  17. #17
    Rédacteur

    Bonjour Jérôme .

    Citation Envoyé par BeanzMaster Voir le message
    Salut, dans ce cas présent ce n'est pas possible, (cela me rappel une discussion avec sqlite3)
    Ici Python fait une "redirection" et attend que l'utilisateur rentre des commandes
    Oui, c'est idiot de ma part : cette commande lance l’interpréteur, elle ne fait pas que donner la version en cours .

    Citation Envoyé par BeanzMaster Voir le message

    Chez moi sous Windows avec TProcessEx, ça fonctionne
    Et chez moi sous Debian, ça fonctionne aussi, je viens de tester .

    Décidément, hier soir (ou plutôt ce matin), je ne devais plus avoir les yeux en face des trous.

    Je vais adapter ces codes à mon application et faire des tests, mais je pense à priori que mon problème est résolu.

    encore et à bientôt,
    amicalement,
    Hervé

  18. #18
    Expert confirmé
    hello,
    on peut lancer un script python avec l'option -u pour qu'il n'y ait pas de "bufferisation" de la sortie console. En python 3 il y a aussi une option dans le print qui permet de "flusher" automatiquent la sortie exemple :
    Code Python :Sélectionner tout -Visualiser dans une fenêtre à part
    print("Hello world!", flush=True)

    pour éviter d'utiliser à chaque fois l'option on peut redefinir le print avec la fonction partial.
    Voici ce que devient alors le code initial python de la discussion :
    Code Python :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    #!/usr/bin/env python
    # coding: utf8
    from functools import partial
    print = partial(print, flush=True)
    import time
    print('Compte à rebours:')
    time.sleep(1.0)
    i = 1
    while i < 11:
         print(11 - i)
         i += 1
         time.sleep(1.0)
    print("C'est parti ! ")

    Cela devrait fonctionner sous windows et linux en python 3
    A noter que j'ai changé le dernier print par rapport au script initial car l'échappement n'était pas bon : ' suivi de ' ne fonctionne pas . Comme on peut utiliser indifféremment les " ou les ' pour les chaînes en python il suffit de bien combiner les deux signes de ponctuation.
    Ami calmant, J.P
    Jurassic computer : Sinclair ZX81 - Zilog Z80A à 3,25 MHz - RAM 1 Ko - ROM 8 Ko

  19. #19
    Expert confirmé
    hello,
    pour comparer l'utilisation de Python for Lazarus et de TProcessEx dans le cas du script python de cette discussion, j'ai créé un petit projet (en pièce jointe). Dans ce projet il y a un TMemo qui affiche la sortie du script python pendant son exécution. Il y a trois boutons :

    1. Un pour lancer le script à partir de Python4Lazarus.
    2. Un autre pour effacer le contenu du TMemo.
    3. Un troisième pour lancer le script à partir de TProcessEx.



    J'ai essayé le programme sous Windows 10 et Centos 8.1 avec Lazarus 2.0.8 et Fpc 3.0.4.
    Ce que j'ai constaté :
    Le programme fonctionne que ce soit pour Python4Lazarus ou TProcessEx sous les deux O.S.
    La partie TProcessEx ne gère pas pour l'instant le scrolling automatique (visualisation du bas du texte affiché).
    Pour Python4Lazarus au départ j'utilisais un composant TPythonGUIInputOutput pour l'affichage dans le TMemo. Sous Linux l'affichage de la sortie du script ne se faisait qu'à la fin de l'exécution du script python. En fait ce qui se passait c'est que les messages n'étaient pas traités pendant l'exécution du script. J'ai donc utilisé un composant TPythonInputOutput à la place avec comme procédure pour la sortie console :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    procedure TForm1.PythonInputOutput1SendUniData(Sender: TObject;
      const Data: UnicodeString);
    begin
       Memo1.Append(Data);
       Application.ProcessMessages;
    end;


    Avec le Application.ProcessMessages, cette fois-ci l'affichage se fait bien au fur et à mesure de l'exécution du script.


    Pour utiliser Python4Lazarus :
    1 - Il faut avoir une version 3 de python installée sous son O.S.
    2 - Il faut installer le paquet PythonForLazarus présent dans le gestionnaire de paquets en ligne.
    3 - Il y a des propriétés à modifier dans le composant PythonEngine1 :
    a - propriété DllName : mettre le nom de la dll de sa version python : exemple python38.dll, libpython3.8m.so
    b - propriété DllPath : mettre le chemin complet où se trouve la dll (en général au même endroit que l'exécutable python).
    Il y a une propriété UseLastKnownVersion qui permet de chercher automatiquement les deux propriétés précédentes mais comme cela ne fonctionne pas toujours, je ne l'ai pas utilisée.
    Attention dans la procédure qui lance TProcessEx j'ai mis le chemin complet de l'exécutable python (pour pouvoir utiliser la version que l'on veut de python si il y en a plusieurs d'installer). Ne pas oublier de le modifier exemple :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    FProcessEx.Executable := 'M:\Dev\python38\python.exe';


    Voici à quoi le projet ressemble :





    Ami calmant, J.P
    Jurassic computer : Sinclair ZX81 - Zilog Z80A à 3,25 MHz - RAM 1 Ko - ROM 8 Ko

  20. #20
    Membre expert
    Salut à tous, j'ai passé une bonne partie de mon après-midi et de ma soirée à confectionner un nouveau composant basé sur TProcessEx, de la nouvelle unité "processutil" disponible dans FPCUpDeluxe et de diverses lecture sur le sujet sur le web.

    Le résultat un TProcessEx boosté renommé en TBZProcessEx

    Dans le zip vous trouverez bien sur les sources de ce TBZProcessEx + une petite démo. Dans le dossier de la démo, se trouve une petite application console "testinput" qui attend que l'utilisateur rentre son nom. Afin de tester l'envois de données vers la console.

    TBZProcessEX, remplacera facilement le composant natif TProcess.

    Il permet d’exécuter des programmes dans une console visible ou invisible.
    Il permet l’interception des données qui se fait via un thread secondaire qui est non bloquant pour l'application.
    Il permet l'envoie d'entrées vers le programme si celui-ci attend une réponse de l'utilisateur.

    On peut récupérer les données intercepter à intervalle régulier.
    Il dispose d'une gestion d'erreur plus complète que le composant natif. Les chemins, le noms de l’exécutable sont vérifiés.
    Les codes d'erreur de sortie et de statut sont gérés.

    Les variables d'environnement du système sont automatiquement ajoutés.
    Sous Windows la console n'étant pas en UTF-8, la conversion des chaines de caractères vers le mode console ou code page est automatiquement gérée.



    Voila. Je n'ai pas testé sous Linux. Je n'ai pas testé tous les messages d'erreur.

    Il y a surement deux trois petites choses à améliorer dans le code (notamment, la gestion des chaines de caractères). Et d'autres options à ajouter. Mais ça sera pour une prochaine fois.

    Je pense que je vais l'incorporer dans ma bibliothèque BZScene

    A vous maintenant !

    Citation Envoyé par jurassic pork Voir le message
    hello,
    on peut lancer un script python avec l'option -u pour qu'il n'y ait pas de "bufferisation" de la sortie console. En python 3 il y a aussi une option dans le print qui permet de "flusher" automatiquent la sortie exemple :
    Code Python :Sélectionner tout -Visualiser dans une fenêtre à part
    print("Hello world!", flush=True)

    pour éviter d'utiliser à chaque fois l'option on peut redefinir le print avec la fonction partial.
    Merci JP c'est bon à savoir cette astuce en Python
    Je m'en vais tester ta petite démo avec Python4Laz
    A+

    Jérôme
    • "L'Homme devrait mettre autant d'ardeur à simplifier sa vie qu'il met à la compliquer" - Henri Bergson
    • "Bien des livres auraient été plus clairs s'ils n'avaient pas voulu être si clairs" - Emmanuel Kant
    • "La simplicité est la sophistication suprême" - Léonard De Vinci
    • "Ce qui est facile à comprendre ou à faire pour toi, ne l'est pas forcément pour l'autre." - Mon pèrei

    Mes projets sur Github - Blog - Site DVP

###raw>template_hook.ano_emploi###