Lancement taches de fond depuis IHM GTK

Lancement taches de fond depuis IHM GTK - Python - Programmation

Marsh Posté le 04-11-2008 à 12:18:40    

Bonjour,
 
Je vous expose mon problème qui sur le principe n'est pas très compliqué:
J'ai créé une petite IHM (avec Glade) qui ne contient qu'un seul bouton à deux états (de type ToogleButton), et j'aimerais que:

  • Si le bouton n'est pas clické, il ne se passe rien
  • Si le bouton est clické, on effectue une action toute simple en tache de fond (print toutes les secondes par exemple)


Je suis parti sur l'utilisation des threads pour effectuer cela mais j'ai l'impression que GTK garde la main et ne la rend jamais.
Je m'attendrais a observer un print périodique toutes les secondes lorsque le bouton est clické et en fait, je n'observe que le premier print, dès que je passe dans le sleep(1), je sors de ma fonction PrintPeriodique.run() et je n'y retourne qu'au click suivant sur le bouton.
 
Voici mon code python et le contenu du fichier Glade associé:

Code :
  1. # -*- coding: cp1252 -*-
  2. import gtk
  3. import gtk.glade
  4. import time
  5. import threading
  6. class PrintPeriodique(threading.Thread):
  7.     def __init__(self, begin):
  8.         threading.Thread.__init__(self, target=self.run)
  9.         self.Terminated = False
  10.         self.begin = begin
  11.     def run(self):
  12.         self.i = self.begin
  13.         while not self.Terminated:
  14.             print self.i
  15.             self.i += 1
  16.             time.sleep(1)
  17.         print "le thread s'est termine proprement"
  18.        
  19.     def stop(self):
  20.         self.Terminated = True
  21.         return self.i
  22.    
  23. # Nous mettons tous nos handlers des signaux gtk dans une
  24. # classe. Ceci nous permet de les lier tous en une seule fois car leurs noms
  25. # sont dans le dictionnaire de la classe.
  26. class GladeHandlers:
  27.     def on_togglebutton1_clicked(event):
  28.         global thread_test
  29.         if widgets['togglebutton1'].get_active():
  30.             widgets['togglebutton1'].set_label("Printing..." )
  31.             thread_test.start()
  32.         else:
  33.             print "On passe ici"
  34.             widgets['togglebutton1'].set_label("Print" )
  35.             i = thread_test.stop()
  36.             thread_test = PrintPeriodique(i)
  37. class WidgetsWrapper:
  38.     def __init__(self):
  39.         self.widgets = gtk.glade.XML('ToogleButton.glade', "window1" )
  40.         self.widgets.signal_autoconnect(GladeHandlers.__dict__)
  41.     def __getitem__(self, key):
  42.         """Ceci nous donne la possibilité de faire : widgets['widget_name'].action()"""
  43.         return self.widgets.get_widget(key)
  44. if __name__ == '__main__':
  45.     widgets = WidgetsWrapper()
  46.     thread_test=PrintPeriodique(0)
  47.     gtk.main()


Code :
  1. <?xml version="1.0" encoding="UTF-8" standalone="no"?>
  2. <!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
  3. <!--Generated with glade3 3.4.3 on Mon Nov 03 10:55:35 2008 -->
  4. <glade-interface>
  5.   <widget class="GtkWindow" id="window1">
  6.     <property name="visible">True</property>
  7.     <child>
  8.       <widget class="GtkToggleButton" id="togglebutton1">
  9.         <property name="visible">True</property>
  10.         <property name="can_focus">True</property>
  11.         <property name="receives_default">True</property>
  12.         <property name="label" translatable="yes">Print</property>
  13.         <property name="response_id">0</property>
  14.         <signal name="clicked" handler="on_togglebutton1_clicked"/>
  15.       </widget>
  16.     </child>
  17.   </widget>
  18. </glade-interface>


 
Merci d'avance pour toute info qui me permettrait d'avancer, mon objectif étant au final de construire une IHM plus complexe comprenant plusieurs boutons, chacun d'entre eux pouvant lancer des actions en tache de fond.

Reply

Marsh Posté le 04-11-2008 à 12:18:40   

Reply

Marsh Posté le 05-11-2008 à 15:49:18    

Re-bonjour,
 
Après pas mal de recherche sur internet, j'ai finalement réussi à faire ce que je voulais, et sans utiliser de threads. J'ai pour cela utilisé la fonction gobject.timeout_add(n,func) qui permet de lancer une fonction "func" toutes les "n" millisecondes.
 
Voici pour information le code que j'ai obtenu:

Code :
  1. # -*- coding: cp1252 -*-
  2. import gtk
  3. import gtk.glade
  4. import time
  5. import gobject
  6. i=0
  7. def PrintSec():
  8.     global Terminated, i
  9.     if not Terminated:
  10.         print i
  11.         i += 1
  12.         return True
  13.     else:
  14.         return False
  15.    
  16. # Nous mettons tous nos handlers des signaux gtk dans une
  17. # classe. Ceci nous permet de les lier tous en une seule fois car leurs noms
  18. # sont dans le dictionnaire de la classe.
  19. class GladeHandlers():
  20.     def on_togglebutton1_clicked(event):
  21.         global Terminated
  22.        
  23.         if widgets['togglebutton1'].get_active():
  24.             widgets['togglebutton1'].set_label("Printing..." )
  25.             Terminated = 0
  26.             gobject.timeout_add(1000,PrintSec)
  27.         else:
  28.             widgets['togglebutton1'].set_label("Print" )
  29.             Terminated = 1
  30. class WidgetsWrapper:
  31.     def __init__(self):
  32.         self.widgets = gtk.glade.XML('ToogleButton.glade', "window1" )
  33.         self.widgets.signal_autoconnect(GladeHandlers.__dict__)
  34.     def __getitem__(self, key):
  35.         """Ceci nous donne la possibilité de faire : widgets['widget_name'].action()"""
  36.         return self.widgets.get_widget(key)
  37. if __name__ == '__main__':
  38.     widgets = WidgetsWrapper()
  39.     gtk.main()

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed