#1 Le 05/04/2009, à 00:15
- Aurel07
[Resolu][Python, Glade] Progressbar qui ne s'actualise pas
Bonsoir a tous !
Je suis debutant en python et gtk, et j'essaie de créer une boite de progression (fenetre de dialogue avec une barre de progression) en python, pygtk et glade.
La barre de progression est supposée avancer toutes les secondes (avec time.sleep(1)), mais lorsque je lance la boucle qui devrait faire tout ca, je ne vois rien, la fenetre ne repond plus, et a la fin de la boucle, la progressbar s'affiche pleine d'un coup et les print(i) s'affichent tous ensemble.
Qu'est ce que je fait mal ? Comment faire en sorte que la progressbar se rafraichisse a chaque iteration de la boucle for ? Et comment garder la main dans mon appli (quand ca tourne, je ne peux pas cliquer sur le bouton de fermeture) ?
Merci !
Et voila le script et le fichier glade :
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os
import subprocess
import time
try:
import pygtk
pygtk.require("2.0")
except:
pass
try:
import gtk
import gtk.glade
except:
sys.exit(1)
class Progress_action:
def __init__(self):
#Initialisation de l'interface de la fenetre de progression
self.progress = gtk.glade.XML("Progress1.glade")
self.progress_win = self.progress.get_widget("dialog1")
self.progress_bar = self.progress.get_widget("progressbar1")
self.dic1 = {"on_dialog1_destroy" : gtk.main_quit,
"on_stop_button_clicked" : self.close_progress,
"on_go_button_clicked" : self.declenche}
self.progress.signal_autoconnect(self.dic1)
def declenche(self, widget):
for i in [0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1]:
self.progress_bar.set_fraction(i)
time.sleep(1)
print i
def close_progress(self, widget):
gtk.main_quit()
if __name__ == "__main__":
Gui = Progress_action()
gtk.main()
Progress1.glade :
<?xml version="1.0"?>
<glade-interface>
<!-- interface-requires gtk+ 2.16 -->
<!-- interface-naming-policy project-wide -->
<widget class="GtkDialog" id="dialog1">
<property name="visible">True</property>
<property name="border_width">5</property>
<property name="type_hint">normal</property>
<property name="has_separator">False</property>
<signal name="destroy" handler="on_dialog1_destroy"/>
<child internal-child="vbox">
<widget class="GtkVBox" id="dialog-vbox1">
<property name="visible">True</property>
<property name="orientation">vertical</property>
<property name="spacing">2</property>
<child>
<widget class="GtkLabel" id="info_label">
<property name="visible">True</property>
<property name="label" translatable="yes">label</property>
</widget>
<packing>
<property name="position">1</property>
</packing>
</child>
<child>
<widget class="GtkProgressBar" id="progressbar1">
<property name="visible">True</property>
</widget>
<packing>
<property name="fill">False</property>
<property name="position">2</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="progress_label">
<property name="visible">True</property>
<property name="xalign">0</property>
</widget>
<packing>
<property name="position">3</property>
</packing>
</child>
<child internal-child="action_area">
<widget class="GtkHButtonBox" id="dialog-action_area1">
<property name="visible">True</property>
<property name="layout_style">end</property>
<child>
<widget class="GtkButton" id="go_button">
<property name="label" translatable="yes">Go</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<signal name="clicked" handler="on_go_button_clicked"/>
</widget>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<widget class="GtkButton" id="stop_button">
<property name="label" translatable="yes">Fermer</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<signal name="clicked" handler="on_stop_button_clicked"/>
</widget>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
</widget>
<packing>
<property name="expand">False</property>
<property name="pack_type">end</property>
<property name="position">0</property>
</packing>
</child>
</widget>
</child>
</widget>
</glade-interface>
Dernière modification par Aurel07 (Le 05/04/2009, à 21:18)
Hors ligne
#2 Le 05/04/2009, à 01:36
- philarmonie
Re : [Resolu][Python, Glade] Progressbar qui ne s'actualise pas
Faut passer par un thread: un processus en parallèle de la boucle principale ( la boucle gtk.main() ) qui s'occupe de gérer la progression de la barre.
Là ta boucle bloque la boucle gtk.main(): ce qui fait que ton application est bloquée (tu n'as plus la main) et que l'état de la barre n'est actualisé qu'une fois la boucle terminée (quand gtk.main() reprend la main).
Dernière modification par philarmonie (Le 05/04/2009, à 01:37)
#3 Le 05/04/2009, à 11:20
- Aurel07
Re : [Resolu][Python, Glade] Progressbar qui ne s'actualise pas
Ok, merci de l'explication !
Ca veut dire qu'il faut que je me renseigne sur le module threading. Encore un truc a apprendre...
Edit : Je mettrais en [résolu] quand j'aurai réussi, je posterai le script alors, pour ceux que ca interesse
Dernière modification par Aurel07 (Le 05/04/2009, à 11:21)
Hors ligne
#4 Le 05/04/2009, à 21:18
- Aurel07
Re : [Resolu][Python, Glade] Progressbar qui ne s'actualise pas
Voila, j'ai la solution. En fait, il fallait aller voir du cote de gobject, et meme si j'ai pas tout compris, ca marche. Voila, le code :
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os
import time
import gobject
try:
import pygtk
pygtk.require("2.0")
except:
pass
try:
import gtk
import gtk.glade
except:
sys.exit(1)
class Progress_action:
def __init__(self):
#Initialisation de l'interface de la fenetre de progression
self.progress = gtk.glade.XML("Progress1.glade")
self.progress_win = self.progress.get_widget("dialog1")
self.progress_bar = self.progress.get_widget("progressbar1")
self.dic1 = {"on_dialog1_destroy" : gtk.main_quit,
"on_stop_button_clicked" : self.close_progress,
"on_go_button_clicked" : self.declenche}
self.progress.signal_autoconnect(self.dic1)
def my_task(self):
for i in [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1]:
time.sleep(1)
self.progress_bar.set_fraction(i)
yield True
yield False
def declenche(self, widget):
task = self.my_task()
gobject.idle_add(task.next)
def close_progress(self, widget):
gtk.main_quit()
if __name__ == "__main__":
Gui = Progress_action()
gtk.main()
On retrouve la question dans la faq pygtk : http://faq.pygtk.org/index.py?req=show& … 23.020.htp
Hors ligne