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?
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)
Salut,
Je n'avais pas encore vu votre réponse.je ne comprends pas la question, il attendais la fin de simul.py pour continuer son execution, mais c'est réglé, en utilisant les subprocess (voir mon post précédent)
Sinon, il manque... .communicate ou un .wait genre:
mais vous allez à priori retrouver le même soucis qu'avec os.system: çà attend la fin de l'exécution en bloquant le gui ;-(
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11 import subprocess filename = 'toto.txt' with open(filename, 'w') as f: p = subprocess.Popen('ls', shell=True, stdout=f, ) p.wait() with open(filename, 'r') as f: print f.read()
=> si vous voulez faire un truc propre, il est préférable de mettre un thread entre le gui et l'exécution du popen. C'est préférable au sens "plus facile" à construire avec un "adaptateur" du gui qui lance une activité asynchrone qui le notifie lorsque c'est terminé. Puis vous pluggez l'activité asynchrone (popen) derrière.
- W
je vous propose ce livre tu peux trouver ton bonheur -|
Voici le lien: [ame="http://www.megaupload.com/?d=AIT9Y7PX"]MEGAUPLOAD - The leading online storage and file delivery service[/ame]
Tout dépend de la richesse du dialogue entre le GUI et l'activité asynchrone.
Ici, vous le limitez à regarder si le fichier de sortie est "prêt" en interrogeant l'état de l'activité via .pool.
L'avantage des threads est de permettre de construire des interfaces plus génériques entre gui et activités asynchrones quelconques que vous spécialisez par la suite.
- W
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager