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

GTK+ avec Python Discussion :

Start/Stop Thread et pygtk !


Sujet :

GTK+ avec Python

  1. #1
    Membre averti
    Inscrit en
    Mars 2010
    Messages
    46
    Détails du profil
    Informations forums :
    Inscription : Mars 2010
    Messages : 46
    Par défaut Start/Stop Thread et pygtk !
    Bjr,
    Bon, encore un problème de thread...
    C'est franchemenet pas évident les thread avec gtk ...
    Pour l'exemple, je veux juste un bouton qui lance un thread,et un autre qui le stop.
    La façon de lancer le thread, qui fonctionne en python, je l'ai trouvé sur le forum (qui date de 2006 qd même )
    Pour l'appliquer en gtk, je vois pas !

    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
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    #! /usr/bin/env python
    # -*- coding:Utf*8 *-*-
    import gtk
    import time, threading
     
    class ComWatcher(threading.Thread):
    	def __init__(self):
    		threading.Thread.__init__(self)
    		self.running = False
     
    	def run(self):
    		"""Le code que le thread devra exécuter."""
    		self.running = True
    		while self.running:
    			time.sleep(1)
    			print 'ok'
     
    	def stop(self):
    		self.running = False
     
     
    class Gui:
    	def __init__(self):
    		self.fenetre = gtk.Window(gtk.WINDOW_TOPLEVEL)
    		self.fenetre.connect("destroy", lambda wid: gtk.main_quit())
    		boite_v = gtk.VBox(True, 2)
    		self.fenetre.add(boite_v)
     
    		bouton = gtk.Button("bouton start")
    		bouton.connect("clicked", self.salut, "bouton start")
    		bouton.show()
    		boite_v.pack_start(bouton, True, True, 2)
     
    		bouton = gtk.Button("bouton bye")
    		bouton.connect("clicked", self.bye, "bouton bye")
    		bouton.show()
    		boite_v.pack_start(bouton, True, True, 2)
     
    		boite_v.show()
    		self.fenetre.show()
     
    		self.watcher = ComWatcher()
     
    	def salut(self,widget,event):
    		self.watcher.start()
     
    	def bye(self,widget,event):
    		self.watcher.stop()
    		self.watcher.join()
     
    	def main(self):
    		gtk.main()
     
     
    start=Gui()
    start.main()
    Merci d'avance à celui qui me sortira de l'impasse

  2. #2
    Membre Expert
    Homme Profil pro
    Inscrit en
    Janvier 2005
    Messages
    1 259
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 1 259
    Par défaut
    Citation Envoyé par AnsuzPeorth Voir le message
    C'est franchemenet pas évident les thread avec gtk ...
    Les threads étant un des trucs les plus durs à utiliser en programmation, c'est dommage que ça soit juste "pas évident" avec gtk+ C'est pas évident non plus de savoir le pb exact que tu rencontres en lisant ton message

  3. #3
    Membre averti
    Inscrit en
    Mars 2010
    Messages
    46
    Détails du profil
    Informations forums :
    Inscription : Mars 2010
    Messages : 46
    Par défaut
    Citation Envoyé par teuf13 Voir le message
    C'est pas évident non plus de savoir le pb exact que tu rencontres en lisant ton message
    Le pb, c'est que ca fonctionne pas !
    Le thread en python, c'est ok, mais appelé depuis la fenêtre GTK, le thread ne se lance pas (enfin si, en cliquant plusieurs fois, j'ai qqles 'ok' qui s'affichent, mais la boucle n'est pas lancé !).
    Si qql'un pouvait donné un exemple, sur la même architecture, qui fonctionne, pour pouvoir se faire une idée.
    Merci !

  4. #4
    Membre chevronné
    Inscrit en
    Janvier 2007
    Messages
    329
    Détails du profil
    Informations forums :
    Inscription : Janvier 2007
    Messages : 329
    Par défaut
    Salut,

    J'essaie aussi d'apprendre les threads en ce moment, du coup j'ai cherché et trouvé un truc 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
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    #! /usr/bin/env python
    # -*- coding:Utf-8 -*-
     
    import threading
    import time
    import gobject
    import gtk
     
    gobject.threads_init()
     
     
    class ComWatcher(threading.Thread):
        def __init__(self):
            threading.Thread.__init__(self)
            self.running = False
     
        def run(self):
            """Le code que le thread devra exécuter."""
            self.running = True
            while self.running:
                print 'ok'
                time.sleep(1)
     
        def stop(self):
            self.running = False
     
     
    class Gui:
        def __init__(self):
            self.fenetre = gtk.Window(gtk.WINDOW_TOPLEVEL)
            self.fenetre.connect("destroy", lambda wid: gtk.main_quit())
            boite_v = gtk.VBox(True, 2)
            self.fenetre.add(boite_v)
     
            bouton = gtk.Button("bouton start")
            bouton.connect("clicked", self.salut)
            boite_v.pack_start(bouton, True, True, 2)
     
            bouton = gtk.Button("bouton bye")
            bouton.connect("clicked", self.bye)
            boite_v.pack_start(bouton, True, True, 2)
     
            self.fenetre.show_all()
            self.watcher = None
     
        def salut(self,widget):
            if self.watcher is None:
                self.watcher = ComWatcher()
                self.watcher.start()
     
        def bye(self,widget):
            if self.watcher is not None:
                self.watcher.stop()
                self.watcher = None
     
        def main(self):
            gtk.main()
     
     
    Gui().main()

    J'ai du recréer un nouveau thread dans la fonction "salut" car sinon ça me renvoyait l'erreur :
    Code text : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Traceback (most recent call last):
      File "test.py", line 48, in salut
        self.watcher.start()
      File "/usr/lib/python2.6/threading.py", line 465, in start
        raise RuntimeError("thread already started")
    RuntimeError: thread already started
    (apparemment on ne peut lancer un thread qu'une seule fois)


    -

  5. #5
    Membre averti
    Inscrit en
    Mars 2010
    Messages
    46
    Détails du profil
    Informations forums :
    Inscription : Mars 2010
    Messages : 46
    Par défaut
    Nickel ...

    J'étais pas loin .... !

    Je n'est pas utilisé gobject, mais gtk.gdk, ca fonctionne aussi ! ( un import de moins )

    Pour lancer plusieurs fois le thread, j'ai juste ajouter un else et un autre nom de thread

    Impeccable !


    Mais pourquoi lancer un thread.init, alors qu'on ne l'appelle plus ensuite ???? (j'avais essayé ensuite avec thread.start() et thread.stop(), sans succès)


    Merci !

  6. #6
    Membre Expert
    Homme Profil pro
    Inscrit en
    Janvier 2005
    Messages
    1 259
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 1 259
    Par défaut
    Citation Envoyé par AnsuzPeorth Voir le message
    Le pb, c'est que ca fonctionne pas !
    Le thread en python, c'est ok, mais appelé depuis la fenêtre GTK, le thread ne se lance pas
    Ok, donc ton problème est que tu 'narrives pas à lancer le thread. Si ton problème était "ce programme ne fonctionne pas", une réponse valable serait "chez moi il se lance sans planter", ce qui ne ferait pas bcp avancer le pb...

  7. #7
    Membre Expert
    Homme Profil pro
    Inscrit en
    Janvier 2005
    Messages
    1 259
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 1 259
    Par défaut
    NB: une fois que vous avez lancé un thread, il faut faire bien attention si vous voulez appeler des fonctions gtk+ dans le thread (en fait, je conseille fortement d'éviter d'essayer d'appeler des fonctions gtk+ dans le thread en question).

  8. #8
    Membre averti
    Inscrit en
    Mars 2010
    Messages
    46
    Détails du profil
    Informations forums :
    Inscription : Mars 2010
    Messages : 46
    Par défaut
    Citation Envoyé par teuf13 Voir le message
    NB: une fois que vous avez lancé un thread, il faut faire bien attention si vous voulez appeler des fonctions gtk+ dans le thread (en fait, je conseille fortement d'éviter d'essayer d'appeler des fonctions gtk+ dans le thread en question).
    Tu pourrais présicer SVP ? Actuellement, dans ce thread, je quitte gtk, modifie l'icone de la fenêtre et l'icone de notifiaction ! C'est grave docteur
    ( ca fonctionne, mais si c'est pas top, autant essayer de faire different !)

    Merci.

    ps: J'essaierais d'être plus précis lors de mes requêtes, j 'ai noté

  9. #9
    Membre chevronné
    Inscrit en
    Janvier 2007
    Messages
    329
    Détails du profil
    Informations forums :
    Inscription : Janvier 2007
    Messages : 329
    Par défaut
    En fait il y a 2 façons d'utiliser les threads : une avec gobject.threads_init() (conseillée), et une avec gtk.gdk.threads_init() (déconseillée).


    L'avantage de gtk.gdk.threads_init(), c'est que ce système autorise les threads à modifier l'interface graphique, mais apparemment ça a l'air d'être pas très clean au niveau de l'implémentation, car la FAQ dit clairement que "this programming style is really not recommended".


    L'autre méthode gobject.threads_init(), qui semble plus propre, ne permet pas aux threads de modifier l'interface, qui doit alors être gérée uniquement dans le thread principal. Pour cela, le thread appelle la fonction gobject.idle_add(...) qui permet d'exécuter une fonction modifiant l'interface dans le thread principal depuis une autre thread (j'espère être assez clair... ).


    Pour info, l'ajout d'un "import gobject" ne change pas grand chose car le module gobject est chargé d'office lorsque tu importes le module gtk (si tu veux vérifier, tape sys.modules.keys() pour avoir la liste des modules chargés).


    -

  10. #10
    Membre averti
    Inscrit en
    Mars 2010
    Messages
    46
    Détails du profil
    Informations forums :
    Inscription : Mars 2010
    Messages : 46
    Par défaut
    Bjr,
    + 2 mois plus tard ...!

    J'ai pas voulu réagir avant de bien cerner le truc.

    Donc, j'en ai conclu que l'utilisation de gobject.idle_add est nécessaire pour modifier un widget sans erreur; On peut modifier sans passer par gobject, mais des erreurs diverses et variées surviennent (pango, insertion, etc,etc ...).

    Si j'ai bien compris, l'utilisation de idel_add, mets en queue la commande et l'execute qd c'est 'libre', ce qui évite les erreurs.

    En tout cas merci pour les explications, ca fait avancer le schmilblick !

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

Discussions similaires

  1. [IIS] start & stop de sites
    Par Dokho1000 dans le forum VB.NET
    Réponses: 1
    Dernier message: 08/07/2007, 12h01
  2. problème avec les commandes run() et start() de Thread
    Par -Juliette- dans le forum Concurrence et multi-thread
    Réponses: 8
    Dernier message: 18/06/2007, 10h08
  3. XP HOME - NET START/STOP Connexion Réseau?
    Par Jean_Benoit dans le forum Windows XP
    Réponses: 2
    Dernier message: 16/03/2007, 07h07
  4. Start/Stop service en masse.
    Par Tchetch dans le forum Windows Serveur
    Réponses: 4
    Dernier message: 29/08/2006, 17h15
  5. [weblogic] start/stop d'une webapp sous weblogic
    Par hari dans le forum Weblogic
    Réponses: 3
    Dernier message: 23/07/2006, 11h41

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