<?xml version="1.0" encoding="UTF-8" ?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
  <title>Latest snippets tagged progressbar python</title>
  <link rel="alternate" href="http://snippets.prendreuncafe.com/snippets/tagged/progressbar+python/order_by/date"></link>
  <id>http://snippets.prendreuncafe.com/snippets/tagged/progressbar+python/order_by/date</id>
  <updated>2008-03-19T09:18:40Z</updated>
  <author>
    <name>Symfony</name>
    <author_email>noreply@symfony-project.com</author_email>
  </author>
<entry>
  <title>Une progress bar mise à jour à partir d'un thread</title>
  <link href="http://snippets.prendreuncafe.com/snippet/78"></link>
  <updated>2008-03-19T09:18:40Z</updated>
  <id>78</id>
  <summary type="html">Dans le cadre d'une application graphique, un traitement long peut être déporté dans un thread à part. Si l'on veut afficher une progress bar, elle doit être mise-à-jour à partir de ce thread.

En PyQt, on utilise un mécanisme de SIGNAL/SLOT pour faire cela.

[code python]
#!/usr/bin/python
# use a progress dialog from a thread

from PyQt4.QtCore import *
from PyQt4.QtGui import *
import time,sys

STEPS=5

class MyThread(QThread):
   def __init__(self,parent):
      super(MyThread,self).__init__(parent)
      self.cancel = False
      
   def run (self):
      for i in range(STEPS):
         if self.cancel: break
         time.sleep(1)
         self.emit(SIGNAL(&quot;increment&quot;))
         print &quot;%d &quot;%(i),

   @pyqtSignature(&quot;&quot;)
   def cancel(self):
      &quot;&quot;&quot;SLOT to cancel treatment&quot;&quot;&quot;
      self.cancel = True
      
class MyAppli(QWidget):
   def __init__(self,parent=None):
      QWidget.__init__(self, parent)
      # create button to start the thread
      self.btnStart = QPushButton(&quot;Start&quot;,self)
      self.connect(self.btnStart, SIGNAL(&quot;clicked()&quot;),
                   self,          SLOT(&quot;on_btnStart_clicked()&quot;))

   @pyqtSignature(&quot;&quot;)
   def on_btnStart_clicked(self):
      &quot;&quot;&quot;Start the treatment in the thread&quot;&quot;&quot;
      self.p = QProgressDialog(&quot;Running...&quot;,&quot;Stop&quot;,0,STEPS-1,self)
      self.th = MyThread(self)
      self.th.connect(self.th,SIGNAL(&quot;increment&quot;),
                              self.incProgress)
      self.p.connect (self.p, SIGNAL(&quot;canceled()&quot;),
                      self.th,SLOT(&quot;cancel()&quot;))
      self.p.show()
      self.th.start()

   def incProgress(self):
      &quot;&quot;&quot;Increment the progress dialog&quot;&quot;&quot;
      self.p.setValue(self.p.value()+1)

if __name__ == &quot;__main__&quot;:
   app = QApplication(sys.argv)
   widget = MyAppli()
   widget.show()
   sys.exit(app.exec_())
[/code]

On commence par créer un simple bouton pour lancer le thread. Lorsqu'il est cliqué, une boite de progression est créée et l'on connecte deux signaux :

+ *increment* pour déclencher la maj de la progressdialog dans le thread principal
+ *canceled* pour annuler le traitement

Puis on affiche la boite et on lance le thread.</summary>
</entry>
</feed>