Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#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