# Autres langages > Python > GUI >  IHM qui freeze lors d'utilisation subprocess

## deusyss

Bonjour  tous,

   Je suis en train de travailler sr la V2.0.0 de mon logiciel Open Source PYXMAKER.

   Je suis confront  un petit soucis pour lequel je n'ai pas vraiment trouv de solution et pour lequel je sollicite votre aide.

   Ce logiciel permet d'automatiser et simplifier la generation de standalone windows et de setup d'install, via IHM,  partir de code source python via un interfacage avec cx_freeze et inno setup. 

Tout se passe de manire graphique, plus de script  crer. Lors de la validation (bouton du dernier ecran, puis bouton de la fenetre pop up qui suit), l'IHM se fige.

   Lors de cette validation, j'appelle une fonction qui fait d'abord appel  cx_freeze, puis  inno setup. Pour ces appels, j'utilise subprocess.popen. Pour etre sur que ces taches s'excute de manire procedurale, j'utilise egalement un subprocess.wait.

   Le probleme est que cela freeze mon IHM, normal me direz vous, on attend la fin de l'execution des commande avant de rendre la main  l'IHM. 

La solution est d'appeler cette fonction dans un thread spar de mon thread normal, puis de capturer la fin de ce thread parallele afin d'avertir l'utilisateur.

   Jusqu'ici je n'ai pas reussi (utiliser de threading.thread), d'ou ce post.

   Les sources sont en PJ, si certaines personnes veulent regarder de plus prs. J'ai galement joint un autre de mes logiciels pour avoir un exemple de sources compatibles (un certains formalisme est obligatoire pour que pyxmaker fonctionne).

    Merci beaucoup d'avance.

EDIT: l'appel se fait dans ihm_pyxmaker.py, aux alentour de la ligne 1690 (rtr = ...)

----------


## tyrtamos

Bonjour,

Si tu avais choisi PyQt4, je t'aurais propos la solution suivante. Peut-tre y a-t-il l'quivalent en PyGtk:

- utiliser QThread plutt que threading pour permettre l'change de messages
- faire que le thread envoie un message de fin  l'ihm
- le message de fin reu par l'ihm excute la mthode prvue dans ce cas
- ce message peut porter des donnes Python pour permettre  l'ihm de rcuprer des rsultats.

Attention: dans la plupart des bibliothques graphiques, il n'est pas permis aux threads de toucher directement au graphique. D'o l'change de messages.

En faisant comme a, l'ihm n'est jamais fig pendant l'excution du thread.

A noter qu'avec threading, il y a aussi une solution: au lieu de bloquer l'ihm en attendant que le thread se termine, on peut tester priodiquement si le thread est toujours en vie avec "isAlive".

----------


## deusyss

Bonjour Tyrtamos,

Je ne connaissais pas isAlive. Je vais chercher de ce cot du coup. Merci beaucoup  ::ccool:: 

Je reviens d'ici de midi pour poster mes resultats de test

----------


## VinsS

Salut,

Tu ne dis pas pourquoi tu n'es pas parvenu  lancer subprocess dans un thread, quel problme cela prsentait il ?

----------


## deusyss

Bonjour VinsS,

En fait j'ai eu deux cas: ou le code de l'appel ne sexcutait pas, ou bien j'avais des messages d'erreurs divers et varis (je ne me rappelle plus lesquels).

Quoiqu'il en soit, cela ne fonctionnait pas. Apres pas mal d'essais, je me suis alors decid  demander un peu d'aide et conseils.

EDIT:
En fait ce que j'ai actuellement c'est (grosso modo) ceci:
--Appel de ma fonction
--Freezage IHM jusqu' fin fonction
--Execution du code qui suit

Ce que je desirerais obtenir au final
--Appel de ma fonction en parallle
--L'IHM continue  normalement, quand la fonction  fini, elle execute une fonction dans le code de l'IHM (declenchement d'une exeption,MAJ d'une variable, ...)

----------


## tyrtamos

Juste un petit complment pour utiliser isAlive dans une ihm.

Une ihm est pilote par une boucle qui traite les instructions (messages, vnements, ...) en attente quand il y en a.

Avec PyGtk, il devrait y avoir une mthode qu'on peut appeler dans le code de l'ihm et qui lui dit: "excuter les instructions en attente, et revenez quand il n'y en a plus". 

Si c'est le cas, voil comment faire juste aprs le code qui a lanc le thread:



```

```

Avec a, l'ihm n'est pas fig, et on sait quand le thread se termine.

----------


## wiztricks

Salut,

Les changes d'informations entre des threads et celle du GUI se font sur les mmes principes: seuls les dtails dimplmentation changent.
Mais l'enfer est dans ces dtails.

Pour PyGTK, ces dtails sont "documentes" dans les FAQ. 

Bonne lecture
- W

----------


## deusyss

Merci beaucoup  vous tous,

wiztricks, ton lien m'a beaucoup aid, je le recommande. changer avec vous tous m'a permis d'apprhender mon probleme sous d'autres angles.

J'ai donc fini par trouver la solution. J'ai oubli ma cl sur mon pc au taf. Je post donc la solution demain et passerai le post en resolu avec des explications

A demain, et merci

----------


## deusyss

Comme promis, voici la solution. Les fichiers sont en PJ.

Comme dans le lien donn par Wiztricks, il s'avre qu'il y a une manire de procder avec les threads en pygtk.

Dans le fichier de l'IHM il faut donc rajouter un "import gobject" et un "import thread". Ensuite dans l'init de la classe IHM, on ajoute "gobject.threads_init()".

On lance le traitement dsir en parallle avec "self.test = thread.start_new_thread(self.fct_gener_setup, (self.dico_param,self.p_print_result))" (dans mon cas). ici self.p_print_result est la fonction qui sera appele par self.fct_gener_setup lorsqu'elle aura fini. 

Dans cette fonction, on utilisera "gobject.idle_add()" pour executer des commandes en dehors du thread parallle.

Les fonctions impacte sont p_print_result(creation), p_win_confirm_response(modification), __init__(modification) et les imports dans ihm_pyxmaker.py, et p_mk_cxf(modification) dans pyxmaker.py

Voil pour les explications. Merci beaucoup  tous pour votre aide  ::ccool:: 

Sujet resolu

----------

