Bonjour à tous,
Voilà dans mon script python, je lance un autre script ce qui fait que le 1er script se bloque et la fenêtre de mon interface devient blanche, comment faire pour executer le second script sans bloquer le 1er?
Bonjour à tous,
Voilà dans mon script python, je lance un autre script ce qui fait que le 1er script se bloque et la fenêtre de mon interface devient blanche, comment faire pour executer le second script sans bloquer le 1er?
utilises des Thread peut être!
Salut,
Je ne sais trop ce que vous appelez 'script': en python vous pouvez appeler des "callables" qui seront méthodes ou fonctions... appelons cela "toto".
Si vous voulez que la chose qui appelle "toto" continue sa vie pendant que "toto" s'exécute, le plus simple est de l'exécuter en "asynchrone" via au choix:
- popen: on exécute un script "externe",
- threading.Thread: dans un contexte de thread,
- multiprocessing.Process: dans un process séparé,
Avec des threads, ca pourrait se passer ainsi:
Comme on suppose que 'toto' viendra livrer des résultats au "lanceur", il va falloir définir les callbacks (les points d'entrées, fonctions) que asy_toto devra appeler lorsqu'il aura terminé ou des informations à passer...
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 import threading asy_toto = threading.Thread(target=toto, args=(1, 2, 3))
Ca se complique:
Notez que j'ai nommé cela "post" car callback un callable de la forme:
Code : Sélectionner tout - Visualiser dans une fenêtre à part asy_toto = threading.Thread(target=toto, args=(1, 2, 3), kwargs=dict(post=callback))
def callback(self, method, *args, **kwds) où il serait "bien" que:
- self: soit la toplevel window ou autre widget qui ait accès à l'event loop
- method: la méthode à appeler et le reste ses arguments.
- *args, **kwds: les arguments à passer
La raison de cela est que l'appelant est aussi une activité "asynchrone" qui a son propre contexte d'exécution. En appelant "method" directement depuis "toto", elle ne s'exécuterait pas dans le "bon" contexte et... cela induit parfois des corruptions mémoires... fatales pour le programme.
Dans le cas général, "post" se contente de "poser" la requête dans une file d'attente que le destinataire "vide" lorsqu'il peut d'en occuper. Mais un GUI dispose déjà d'une file d'attente "utilisable".
Avec Tkinter, les points d'entrées sont .after ou .after_idle...
Le callback s'écrit alors:
Bon ben y'a plus qu'à...
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 def callback(self, method, *args, **kwds): self.after_idle(method, *args, **kwds)
- W
Merci beaucoup pour ces clarifications,
Je n'ai pas l habitude de manipuler les threads et le multiprocessing, disons que je veux lancer un autre programme python (simul.py) à partir de mon premier programme, je crois que simul.py necessite un process séparé, il devra entre autre modifier des fichiers texte que mon premier programme utilisera, avant celà j'utilisais un simple os.system("python simul.py"), mais la fenêtre de mon premier programme se bloquait, une autre remarque,simul.py utilise plus de 80% du CPU quand il s'execute, que pensez vous de tout ça?
j'ai finalment utilisé un process en utilisant Popen:
Y'a t'il un moyen d'avoir le stdout dans un fichier text? et sans pour autant attendre que ce process se sermine pour que le 1er continue à s'éxecuter?
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 proc= subprocess.Popen("python simul.py", shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
Oui, il suffit de lui en passer un ouvert en écriture, à la place de subprocess.PIPE :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 file = open("chemin/vers/fichier", "+w") proc= subprocess.Popen("python simul.py", shell=True, stdout=file, stderr=subprocess.STDOUT)
Partager