IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
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

Python Discussion :

Python, thread et commande système


Sujet :

Python

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 13
    Points : 10
    Points
    10
    Par défaut Python, thread et commande système
    Bonjour,

    Je me suis mis récemment à Python afin de développer des applications pour Gnome en utilisant la bibliothèque PyGTK. Cependant ma question ne concerne pas PyGTK. Actuellement, j'ai ma petite GUI et quand je clique sur le bouton "Ok" je veux que commande système s'exécute. J'ai essayé avec la commande ls par exemple et tout va bien en revanche j'ai tenter d'exécuter une commande dont le traitement est beaucoup plus long (encodage d'une vidéo). J'ai ainsi remarqué que ma GUI se fige (interface grisée) et impossible de l'utiliser, j'ai pensé que c'était donc un problème lié au fait que mon script Python n'utilisait pas de thread. J'ai donc déporté l'exécution de la commande système dans un thread mais le gros soucis que j'obtiens et que le thread ne démarre pas toujours dès l'appuie sur le bouton. Parfois oui parfois il faut attendre et on peut comme ceci lancer plusieurs fois la commande ce qui peut vite mettre à genoux le PC. Avez-vous une idée d'où cela peut provenir et aussi un moyen de régler ce soucis ?

    Voilà comment je gère le thread si ça peut aider.
    Le bouton ok va lancer la méthode suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    def integrate(self, source = None, event = None):
     
    	integration = Integration(self.video, self.text, self.another_video)
    	integration.start()
    Et donc lancer un thread grâce à :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    class Integration(threading.Thread):
    	def __init__(self, video, text, another_video):
    		threading.Thread.__init__(self)
    		self.video = video
    		print 'Récuparation video = ' + self.video
    		self.text = text
    		print 'Récuparation text = ' + self.text
    		self.another_video = another_video
    		print 'Récuparation another_video = ' + self.another_video
     
    	def run(self):
    		print self.video + ' | ' + self.text + ' | ' + self.another_video

  2. #2
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 480
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 480
    Points : 9 277
    Points
    9 277
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    Il serait sage que tu ajoutes un drapeau pour empêcher qu'un 2ème clic sur le bouton relance le thread. Tu pourrais même, en utilisant ce drapeau et la méthode integrate(), transformer le bouton en "arrêter".

    Autre suggestion: si tu arrêtes ton gui et que le thread est en cours, le gui devrait attendre que le thread se termine pour s'arrêter. Conclusion: mets le thread en daemon.

    Sinon, la variable "integration" est une variable locale à la méthode integrate(), c'est à dire qu'elle disparaîtra juste après le start()... en abandonnant lâchement le thread à son triste sort. Il faut utiliser une variable appartenant à l'instance de classe de la classe du gui: self.integration.

    Tyrtamos

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 13
    Points : 10
    Points
    10
    Par défaut
    Citation Envoyé par tyrtamos Voir le message
    Sinon, la variable "integration" est une variable locale à la méthode integrate(), c'est à dire qu'elle disparaîtra juste après le start()... en abandonnant lâchement le thread à son triste sort. Il faut utiliser une variable appartenant à l'instance de classe de la classe du gui: self.integration.
    Exact le fait de la passer en variable de classe permet de résoudre mon problème d'après mes quelques tests. Je vais prendre en considération tous ces précieux conseils pour les appliquer.
    Merci beaucoup

    Edit : Hum finalement ça me fait toujours des choses bizarres. Le thread a tendance à ne pas vouloir s'exécuter quand même.

  4. #4
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 480
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 480
    Points : 9 277
    Points
    9 277
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    Voilà un exemple de ton code qui marche:

    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
     
    #!/usr/bin/python
    # -*- coding: utf-8 -*-
     
    import Tkinter
    import threading
     
    class Integration(threading.Thread):
        def __init__(self, video, text, another_video):
            threading.Thread.__init__(self)
            self.video = video
            print u'Récupération video = ' + self.video
            self.text = text
            print u'Récupération text = ' + self.text
            self.another_video = another_video
            print u'Récupération another_video = ' + self.another_video
     
        def run(self):
            print self.video + ' | ' + self.text + ' | ' + self.another_video
     
    class Application(Tkinter.Frame):
        def __init__(self, master=None):
            Tkinter.Frame.__init__(self, master)
     
            self.grid()
            self.bouton = Tkinter.Button(self, text="vidéo", command=self.integrate)
            self.bouton.grid()
     
            self.integration = None
     
        def integrate(self, event=None):
            if self.integration==None or (not self.integration.isAlive()):
                self.integration = Integration("video", "texte", "autre_video")
                self.integration.setDaemon(True)
                self.integration.start()
     
    fen = Tkinter.Tk()
    app = Application(fen)
    fen.mainloop()
    Tyrtamos

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 13
    Points : 10
    Points
    10
    Par défaut
    Bonjour,

    Yep ton code fonctionne nickel et c'est ce que j'ai dans ma version PyGTK.
    Pour le thread fait toujours des siennes.
    Je joins en PJ, le code si ça tente quelqu'un de regarder car je ne sais plus où regarder. Si ça se trouve c'est quelque chose de tout bête que j'ai manqué...
    Sinon, pour info, il y a un moyen de mettre une priorité au thread ?
    Fichiers attachés Fichiers attachés

  6. #6
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 480
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 480
    Points : 9 277
    Points
    9 277
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    A ma connaissance, ce n'est pas possible de modifier la priorité d'un thread sous Python. Mais ça devrait être possible avec un processus.

    Je ne peux pas tester ton code car je n'ai pas gtk.

    Pour la partie thread, je n'ai rien vu d'anormal à part les ";" en fin de certaines lignes.

    Cependant, il me semble que lors d'un appel à des programmes externes (comme os.system()) long, il est possible que le thread ne puisse rendre correctement la main. Certains forums conseillent dans ce cas de lancer la commande os.system() avec un "&" à la fin de la commande shell. Sous linux, cela fait que la commande est lancée en tâche de fond, en rendant tout de suite la main à la console. Sous Windows, je ne sais pas: il faut essayer. Cela donnerait, par exemple:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    os.system('zenity --info --text="Subtitles integration has been sucessful." &')
    Tyrtamos

  7. #7
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 13
    Points : 10
    Points
    10
    Par défaut
    Citation Envoyé par tyrtamos Voir le message
    Pour la partie thread, je n'ai rien vu d'anormal à part les ";" en fin de certaines lignes.
    Moi et mon habitude au C et Java

    Citation Envoyé par tyrtamos Voir le message
    Cependant, il me semble que lors d'un appel à des programmes externes (comme os.system()) long, il est possible que le thread ne puisse rendre correctement la main. Certains forums conseillent dans ce cas de lancer la commande os.system() avec un "&" à la fin de la commande shell. Sous linux, cela fait que la commande est lancée en tâche de fond, en rendant tout de suite la main à la console.
    Je rajoute immédiatement.
    Apparemment, la commande avec mencoder donc le thread à tendance à partir après une autre action sur l'interface. Par exemple, une action dans le menu bar (sélection de préférences). Pour Windows c'est pas vraiment un soucis, c'est un petit programme perso pour mon bureau Gnome

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Masquer une commande système dans python
    Par Mysti¢ dans le forum Général Python
    Réponses: 5
    Dernier message: 03/11/2006, 16h33
  2. Commandes systèmes avec pl/pgsql
    Par Takayanagi dans le forum PostgreSQL
    Réponses: 4
    Dernier message: 11/08/2006, 12h36
  3. exécuter une commande système à partir de sqlplus?
    Par c_moi_c_moi dans le forum Oracle
    Réponses: 24
    Dernier message: 08/11/2005, 15h11
  4. [Process] éxecution d'une commande système
    Par alex'l dans le forum API standards et tierces
    Réponses: 12
    Dernier message: 13/09/2005, 17h29
  5. Commande Système
    Par siaoly dans le forum Langage
    Réponses: 5
    Dernier message: 14/07/2005, 00h25

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo