# Autres langages > Python > GUI >  Problme d'interface graphique

## Ovopck

Bonjour,  tous!

Je viens vers vous car je n'arrive pas  rsoudre un problme.

Je souhaiterais crer une interface graphique constitue d'un bouton quitt et d'un canevas qui affiche un dfillement d'images se trouvant dans le mme dossier (toutes les secondes, via time.sleep(1) ).

Les images tant du JPG, j'utilise PIL mais pour la fentre j'aurrais vraiment une prfrence pour wxpython ou encore PyQt parce que Tkinter... c moyen niveau qualit graphique.

Une autre petite question : Pour les captures d'cran avec PIL, je peux choisir le format d'enregistrement via l'extension mais peut t-on choisir la qualit ou la rsolution? (je voudrais une infrieure)

Voila, j'espre avoir de vos nouvelles rapidement, Merci BCP!!!!

----------


## nyko77

Bonjour,
C'est facilement ralisable avec wxpython. (avec pyqt aussi, mais je suis moins  l'aise).
Il ne faut pas utiliser time.sleep(1) car cela bloque le mainloop ( moins d'utiliser un thread).
il existe wx.Timer prvu  cet effet.
Voici un exemple:
Je ne sais pas exactement quelle traitement tu veux effectuer avec pil, ici je redimensionne simplement l'image. Si tu ne veux pas faire de traitement Pil est inutile ici.



```

```

----------


## Ovopck

Ah merci beaucoup niko, je bloquait surtout sur le dfilement de l'image : je savait en faire apparatre une mais pas en changer. Ton script correspond trs bien  ce que je cherche, merci bcp!!!

Par contre, je ne l'aurais pas fait de cette manire, est-t-il possible d'avoir un thread de traitement (script, fichier, etc....) et un thread qui ne gre que l'interface? Parce que je ne comprend pas pourquoi tu as mi le loop  la fin et non dans une fonction.

Perso j'utilise cette mthode pour les threads :

monthread1=threading.Thread(None, mafonction1, None)
monthread2=threading.Thread(None, mafonction2, None)
monthread1.start()
monthread2.start()

Pour une utilisation directe ca ne me pose pas de problme mais si je le compile, une fois la fin du programme atteinte il se termine mme si des threads sont encore ouverts, je suis donc oblig de mettre une boucle pour autoriser la fermeture.

----------


## nyko77

heu...
c'est bizarre comme faon de faire (enfin je trouve).

Je ne vois pas l'intrt de mettre 2 threads.
Le cot graphique est ton programme principale, donc pas besoin de le mettre dans un thread. D'o le mainloop en dehors d'une fonction ou d'un thread (a commence  tre tordu sinon). a fait une boucle infini qui vrifie les vnements, c'est dj une sorte de thread.
Ensuite le wx.Timer est aussi un thread, c'est une juste une faon plus pratique dans ton cas que les thread standard de python.




> Pour une utilisation directe ca ne me pose pas de problme mais si je le compile


Qu'appels tu "compile"?




> je suis donc oblig de mettre une boucle pour autoriser la fermeture


Avec le wx.Timer je pense pas que tu aies ce problme(je suis vraiment pas sr). As tu essay?
Si c'est le cas, comme tu le dis, il suffira de mettre une boucle dans le onQuit pour vrifier que la fonction est bien terminer.

Dans l'exemple que j'ai donne, il faut juste faire attention que le traitement ne dur pas plus longtemps que l'appel du Timer (1000ms). C'est dj pas mal pour le traitement d'une photo.

De plus c'est souvent compliqu d'utiliser les thread avec wxpython, car a rentre en conflit avec le mainloop.

Ensuite, j'ai peut-tre pas bien compris ce que tu veux faire. Je pourrais t'en dire plus, si tu me convaincs que wx.Timer ne fonctionne dans ton cas .

----------


## Ovopck

Accroche toi xD!

Alors pour les threads, j'ai toujours pris l'habitude de sparer les fonctions de mes programmes dans des threads diffrents, par exemple : 

En ce moment je suis sur un gros projet avec un gestion client serveur. Mon programme a quasiment 20 fonctions chacune dans un thread diffrent. Et les 20 ne sont pour qu'un client... aprs il faut les multiplier par le nombre de connexion....

Cependant, pour que certaines fonctions puissent fonctionner, d'autre doivent tre arrt c'est pour cela que j'utilise beaucoup de thread + un autre pour la gestion de ces derniers.

Fonctionnement du thread de gestion:

Le contrle se fait par variable global (3 variables pour chaques thread) :
1 - Thread demarr
2 - Contrle du bon fonctionnement priodique. (dtection du changement de valeur indique que le thread fonctionne toujours)
3 - Demande d'arret (l'arret c'est le thread concern qui l'xcute en testant la valeur de la variable)

Il y a 2 autres variables mais celles-ci sont plus pour optimiser le tout.

Donc pour revenir, oui j'ai besoin que l'interface soit dans un thread car je pourrais avoir besoin d'en crer des copies pour chaque client (par ex une fentre s'ouvre avec des info a chaque fois qu'un client se connecte).

De cette facon, j'ai juste a dmarrer le mme thread pour chaque client avec un argument qui identifie le numro du client.

Il y a aussi un problme pour les connexions rseau : mon serveur doit pouvoir grer un grand nombre de connexion et pour chacune d'entre elles, 20 fonctions utilisent le rseau... Ya vraiment intrt  ce qu'il y ai un contrle de thread parce que si tout ce petit monde envoi ses infos en mme temps.... Pour l'instant j'ai pas encore trouv d'autre solutions mais elle me convient trs bien.

Pour "compiler" je veux en ralit dire en faire un excutable portable. Et donc le problme est dans la cas o mon programme est "compil", si jamais il atteint la fin du prog, il s'arrette (mme si d'autre thread son encore en cours....). Pour rsoudre a ca, je met mon contrle de thread dans le corps du programme et comme il est dans une boucle (normal vu qu'il est cens contrler en permanence), le programme n'arrive jamais  la fin.

Pour le wx.Timer, je n'est pas essay puisque selon ma mthode de gestion avec les thread, il ne bloque que le thread concern et non les autres, ce qui est doublement mieu.

Je me suis apercu trs rcement que les mthodes des autre programmeur ne me convenait pas. C'est peut-tre la pens de tout les programmeurs.... Tout ca pour dire que cette facon d'utiliser les threads me permet une bonne gestion des taches  effectuer en mme temps et de facon squentielle mme si cela peut parate trange!

++

----------


## nyko77

Bon d'accord.
Et a fonctionne comme tu le souhaites alors?

----------


## Ovopck

Oui, avec ton code que j'ai un peu modifi pour qu'il puisse tre prit en compte par la gestion de thread, il fonctionne  merveille.

Dumoins, je n'ai fait que des tests avec 3 faut client, il me faut encore terminer tout mon projet et vrifier qu'il n'y ai pas de problme avec quelques dixaines de connexion.

Merci!!!

----------


## Ovopck

Recoucou, c'est encore moi. 

J'ai un autre petit problme avec mon interface graphique. Je poste ici car le titre convient aussi  ce nouveau.

Je vient de me lancer dans Pyqt (je sais que tu n'es pas trs alaise mais j'essaye quand mme). J'utilise QT designer pour faire mon interface graphique et j'ai fait quelque chose de pas mal du tout. Maintenant mon problme est que je ne sais pas comment faire pour faire "communiquer" l'interface  mon prog.

Ex : J'ai un bouton. Qu'elle est la commande pour qu'il change une variable une fois que jai appuy dessus?

Connatrais tu des tutoriels qui explique cela?

Merci!

----------


## VinsS

Hello, a n'a rien de compliqu, mais peux-tu nous montrer un exemple simplifi de code ?

Est-ce que tu bloque sur le signal-slot ?



```

```

dans cet exemple update_viewer est dans la mme classe, mais cela ne change rien.

vincent

----------


## Ovopck

Oula oula, l ca y est : JE SUIS PAUMER!!!

Bon alors, programmer en python aucun problme, gestion rseau aucun problme... mais niveau graphique, je sais :

f=Tk()

faire des label, des canvas, ....

f.mainloop()

Et voila (surtout que ca, c'tait du tkinter)

La je dbute en Qt parce que je trouve ca dj bien mieu fait et qu'aprs QT designer je gagne des journes en temps de programmation.

Donc, pour mon interface graphique, rien de trs compliqu :

Titre, entry, liste, case  coches, etc....

J'enregistre en .ui, je compile avec pyuic, je copie le texte dans le thread graphique de mon prog et c'est ici que je bloque.

Comment faire apparatre le contenue de variables global dans cadres graphique et comment modifier des variables avec des pushboutons ou encore enregistrer le contenu d'un texte dans un entry dans une variable?

----------


## VinsS

Je ne saisis pas trs bien, ton thread n'est pas isol du reste du monde, il peut toujours traiter des arguments qui ne sont pas dans son propre espace de nom et mme des arguments d'une autre classe. Je dirais presque que c'est l'enfance de l'art.

Les entry sont encore plus facile  utiliser



```

```

o ma_fonction rcuprera la nouvelle valeur de l'entry du moment que foo soit accessible.

vincent

----------


## Ovopck

Rolala, je suis coul!

C'est quoi foo?

Et mon interface peut tre considre comme isole sauf qu'elle "communique" aux aux thread via des variables globales et des boucles.

Quand la fonction sera-t-elle excute? A chaques changements du contenue de l'entry?

----------


## VinsS

Montre nous un exemple simplifi, parce que j'ai du mal  imaginer l'architecture de ton appli.

Elle n'avait pas d'interface graphique avant ? Si c'est le cas, et que tu veux faire l'interface avec Qt, instancie-la au dmarrage de ton appli et non dans un thread, a n'a pas de sens.

Ou alors, cette interface n'est qu'un accessoire  ton appli qui n'apparat que contextuellement et dans ce cas cela s'appelle une boite de dialogue.

Quel rapport avec le dfil d'images de ton premier post ?

vincent

Ah oui,

[ame="http://fr.wikipedia.org/wiki/Foo"]http://fr.wikipedia.org/wiki/Foo[/ame]

----------


## nyko77

> J'enregistre en .ui, je compile avec pyuic, je copie le texte dans le thread graphique de mon prog et c'est ici que je bloque.


Je n'ai pas beaucoup utilis qt designer, mais je pense que tu peux tendre ta classes avec celle de la classe cre par le pyuic, ou comme dit VinsS, l'instancier au dmarrage. a dpend comment tu procdes.

Programmes-tu en objet? je vois que tu parles de variables globales...




> instancie-la au dmarrage de ton appli et non dans un thread, a n'a pas de sens.


Il n'y a pas que moi qui trouve ta faon de faire bizarre.

C'est pratique d'utiliser un RAD, a fait gagner du temps, mais il faut tout de mme connaitre un minimum la library que tu utilises, sinon a deviens vite compliqu.

C'est vrai qu'un bout de code permettrait d'y voir plus clair.

Si tu es plus  l'aise avec wxpython, tu peux utiliser wxFormBuilder. C'est un peu moins performant que qt designer, mais a reste trs convenable.

----------


## Ovopck

Je vais avoir beaucoup de mal  vous donner un code simplifier de mon programme puisse qu'il doit faire dans les 1000 lignes... D'o mon intention de bien organiser mon programme en thread. D'ailleurs j'ai mi une semaine entire rien que pour organiser mon programme avec des logiciels comme DIA.

Auparavant, mon programme n'avait que la console basique de python avec de temps en temps des print dessus et c'tait tout. L mon but est de cacher cette console et la remplacer par une vrai interface graphique qui me permet d'interagir avec mon prog. Ce n'est absolument pas une simple boite de dialogue.

Il n'y a pas vraiment de rapport avec ma premire question sauf que le domaine tait le mme (Qt) ... Sans compter que tu m'avait dj rpondu  ma premire question, et qu'il y avait plus de chance que la rponse  la deuxime soit plus claire vu le contexte.

Pour le dfilement d'image, une fonction de mon soft est l'administration a distance. D'o le fait de tlcharger les screens client toutes les secondes et de les afficher dans un canvas. Je suis aussi en train de travailler sur PIL pour n'envoyer par socket que les modifications par rapport  l'image prcdente qui limiterai le temps de transfert et la bande passante.

En ce qui concerne ma mthode pour inclure une interface graphique dans mon programme dj xistant, j'ai choisi le thread et les variables globales pour les raisons suivantes :

- C'est limite mission impossible de ce retrouver dans mon programme d'o l'envie de mettre la fonction qui gre l'interface graphique dans un thread, bien spar des autres.

- De plus, pour chaques threads existant, il y a une multitude de variables globales qui renseignent sur son tat et sur ce qu'il doit faire. Voila pourquoi je pensait tout simplement ajouter un thread graphique qui irait directement piquer les infos sur les globales...

J'espre qu'avec ces complments d'informations, vous comprenez mieux ma faon de procder, qui je l'avoue, dans pour un programme basique, serait totalement bizarre.

Pour wxpython, j'en suis au mme point qu'avec QT : je sais faire l'interface graphique sur le logiciel mais je ne sais pas comment faire pour rcuprer, afficher les globales et les modifier en fonction des events dans l'interface.

----------


## VinsS

J'ai l'impression que tu travailles de faon empirique.




> - C'est limite mission impossible de ce retrouver dans mon programme d'o l'envie de mettre la fonction qui gre l'interface graphique dans un thread, bien spar des autres.


Quelques rgles de bases:

-Ton interface principale doit tre instancie au dmarrage de l'apply, elle sera disponible pour tous les constituants de ton programme.

-Les variables globales sont interdites depuis l'dit de Nantes.

-Place les connections de tous tes widgets dans l'application principale et non dans le code de l'interface parce que tu auras surement  les modifier plus tard.

-Trop de threads tue le thread, n'oublie pas que ton apply ne fontionne pas plus vite avec des threads, cela permet simplement  l'utilisateur de pouvoir continuer son traitement pendant qu'une autre tche s'accomplit en arrire-plan, un processeur ne fait qu'une chose  la fois.

-Si tu veux aussi traiter des images, le format optimis pour l'cran est le pixmap et il est impossible de traiter les pixmap en dehors du thread principal (main loop).

Les conseils que nous te donnons, ici, vont dans le sens d'une simplification relle de ton travail, il ne faut pas craindre de revoir totalement le concept de base, tu y gagneras beaucoup de temps plus tard.

Quitte  tout rcrire, qui ne l'a jamais fait ?

vincent

----------


## Ovopck

AAAaaa j'le crois pas, je ne pensait pas avoir de rponse vu que je n'ai pas recu d'e-mail et je ne faisait que passer par la....

Donc pardon pour mon retard




> J'ai l'impression que tu travailles de faon empirique.


Oh non justement, j'ai tellement de fonction que je suis oblig de faire ca pour les sparer, ne pas tre bloqu par des scripts bloquant, etc....

Mon prog est un client/serveur fonctionnant sur 10 ports :
1 port pour la commande (ordre)
les 9 restants pour les transferts et autres.....

1 ordre arrive sur le thread de connexion, il est interprt, le thread de connexion lance le thread de fonction avec en argument le port donn par le serveur aprs l'ordre. le thread de fonction se connecte a un thread tout juste crer qui est sur le serveur via le port donn.

L je ne voit pas comment je pourrais me passer de threads...




> -Ton interface principale doit tre instancie au dmarrage de l'apply, elle sera disponible pour tous les constituants de ton programme.


La je n'est pas besoin de cela. Elle doit juste afficher des variables globales et en modifier...




> -Les variables globales sont interdites depuis l'dit de Nantes.


Gn?




> -Place les connections de tous tes widgets dans l'application principale et non dans le code de l'interface parce que tu auras surement  les modifier plus tard.


Impossible a cause des script bloquant. Il doit pouvoir faire plusieurs transfert en mme temps + rception et retour des ordres sur le port de commande.





> -Trop de threads tue le thread, n'oublie pas que ton apply ne fontionne pas plus vite avec des threads, cela permet simplement  l'utilisateur de pouvoir continuer son traitement pendant qu'une autre tche s'accomplit en arrire-plan, un processeur ne fait qu'une chose  la fois.


OOOooo oui, niveau thread je suis tout a fait  la page. Mon but n'est que de dvelopper bien sparment des fonctions indpendantes




> -Si tu veux aussi traiter des images, le format optimis pour l'cran est le pixmap et il est impossible de traiter les pixmap en dehors du thread principal (main loop).


Je ne connait pas le pixmap, j'utilise PIL mais je suppose qu'il doit s'en occup en arrire plan.




> Les conseils que nous te donnons, ici, vont dans le sens d'une simplification relle de ton travail, il ne faut pas craindre de revoir totalement le concept de base, tu y gagneras beaucoup de temps plus tard.
> 
> Quitte  tout rcrire, qui ne l'a jamais fait ?


J'en suis dj  ma 4eme rcriture de mon apply faute d'organisation des taches et depuis que j'utilise les threads, tout va nettement mieu.

Pour revenir l o je bloque toujours :

J'ai des variables globales, comment les afficher dans une interface et comment les modifier via des entry, ..... + bouton

Voila, merci!

PS: J'ai fait un modle pour prvoir  l'avance  quoi mon interface va ressembler (simple image bmp). N'empche qu'elle parat vraiment raliste. Si ca peut aider (elle n'est pas fini). Voir pice jointe

----------


## VinsS

Ah, le gothique c'est chic,

Je te met un exemple de connexions basiques, tu devrais t'en sortir avec a:



```

```

tu remarqueras que j'ai mis les fonctions qui reoivent les signaux ainsi que la gestion du plainTextEdit hors de la classe de l'interface pour te montrer qu'elle peut-tre gre de "l'exterieur".

Enjoy, vincent

----------


## Ovopck

H non pas Gothic mais Celtique!!!

Je ne suis pourtant pas trs dou pour tout ce qui est graphisme mais je ne suis pas mcontent de moi, surtout sous paint xD!!!

Merci pour cette portion de code, je vais potasser ca, je vous tient au courant.

Merci encore, a bientt!!!

PS : je met en rsolu car je considre que le plus gros a t fait.

----------


## Ovopck

10 minutes plus tard....

MAGNIFIQUE!!!!!
C'est ce que je cherchais!!!!
Maintenant, je n'est plus qu' ajouter, dans les fonctions, le changement des variables globales!!!

MERCI MERCI MERCI

Et pour ce qui en est de l'affichage d'une variable dans un Label, comment faire?

----------

