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 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185
| #!/usr/bin/python
# -*- coding: utf-8 -*-
from __future__ import division
# Python 2.7
import sys, os, time, urllib
from PyQt4 import QtCore, QtGui
#############################################################################
class Abort(Exception):
"""classe d'exception crée pour l'arrêt du téléchargement avant la fin"""
pass
#############################################################################
class Telecharger(QtCore.QThread):
"""Thread de téléchargement"""
#========================================================================
def __init__(self, source, destination, parent=None):
super(Telecharger,self).__init__(parent)
self.source = source
self.destination = destination
self.stop = False
self.pause_etat = False
#========================================================================
def run(self):
# lancement du téléchargement
try:
filename, msg = urllib.urlretrieve(self.source, self.destination,
reporthook=self.infotelech)
messagefin = u"Téléchargement terminé\n\n" + unicode(msg)
except Abort:
messagefin = u"Téléchargement avorté"
# fin du thread: émission du message de fin
#self.emit(QtCore.SIGNAL("fintelech(PyQt_PyObject)"), messagefin)
self.emit(QtCore.SIGNAL("fintelech(PyQt_PyObject)"), messagefin)
#========================================================================
def infotelech(self, telechbloc, taillebloc, totalblocs):
"""reçoit les infos de progression du téléchargement"""
# nécessaire pour stopper le téléchargement avant la fin
if self.stop:
raise Abort
while self.pause_etat:
if self.stop:
raise Abort # pour que l'arrêt marche aussi en situation 'pause'
time.sleep(0.1)
# envoie les infos de progression à la fenêtre graphique
self.emit(QtCore.SIGNAL("infotelech(PyQt_PyObject)"),
[telechbloc, taillebloc, totalblocs])
#========================================================================
def pause(self):
# permet la mise en pause du téléchargement
self.pause_etat = True
#========================================================================
def reprise(self):
# permet la reprise du téléchargement après une pause
self.pause_etat = False
#========================================================================
def stoptelech(self):
# permet l'arrêt du téléchargement avant la fin
self.stop = True
#############################################################################
class Fenetre(QtGui.QWidget):
#========================================================================
def __init__(self, parent=None):
super(Fenetre,self).__init__(parent)
self.label1 = QtGui.QLabel(u"Adresse web du fichier à télécharger:", self)
self.fichierweb = QtGui.QLineEdit(self)
self.label2 = QtGui.QLabel(u"Adresse sur le disque:", self)
self.fichier = QtGui.QLineEdit(self)
self.depart = QtGui.QPushButton(u"Départ", self)
self.depart.clicked.connect(self.depart_m)
self.pause = QtGui.QPushButton(u"Pause", self)
self.pause.clicked.connect(self.pause_m)
self.pause_etat = False
self.stop = QtGui.QPushButton(u"Stop", self)
self.stop.clicked.connect(self.stop_m)
self.barre = QtGui.QProgressBar(self)
self.barre.setRange(0, 100)
self.barre.setValue(0)
posit = QtGui.QGridLayout()
posit.addWidget(self.label1, 0, 0, 1, 3)
posit.addWidget(self.fichierweb, 1, 0, 1, 3)
posit.addWidget(self.label2, 2, 0, 1, 3)
posit.addWidget(self.fichier, 3, 0, 1, 3)
posit.addWidget(self.depart, 4, 0)
posit.addWidget(self.pause, 4, 1)
posit.addWidget(self.stop, 4, 2)
posit.addWidget(self.barre, 5, 0, 1, 3)
self.setLayout(posit)
self.telech = None
#========================================================================
def depart_m(self):
if self.telech==None or not self.telech.isRunning():
# initialise la pause
self.pause_etat = False
self.pause.setText(u"Pause")
# initialise la barre de progression
self.barre.reset()
self.barre.setRange(0, 100)
self.barre.setValue(0)
# démarre le téléchargement
source = unicode(self.fichierweb.text())
destination = unicode(self.fichier.text())
if destination == u"":
destination = os.path.basename(source)
self.fichier.setText(destination)
self.telech = Telecharger(source, destination)
self.connect(self.telech, QtCore.SIGNAL("infotelech(PyQt_PyObject)"),
self.infotelech)
self.connect(self.telech, QtCore.SIGNAL("fintelech(PyQt_PyObject)"),
self.fintelech)
self.telech.start()
#========================================================================
def pause_m(self):
"""Méthode appelée avec un clic sur le bouton pause/reprise"""
if self.pause_etat:
# l'état est en pause: il faut donc reprendre le téléchargement
self.pause_etat = False
self.pause.setText(u"Pause") # modif libellé du bouton pause
self.telech.reprise() # donner l'ordre de reprise au thread
else:
# l'état est en téléchargement: il faut donc passer en pause
self.pause_etat = True
self.pause.setText(u"Reprise") # modif libellé du bouton pause
self.telech.pause() # donner l'ordre de pause au thread
#========================================================================
def infotelech(self, msg):
"""lancé à chaque réception d'info sur la progression du téléchargement"""
telechbloc, taillebloc, totalblocs = msg
if totalblocs > 0:
# on a la taille maxi: on peut mettre à jour la barre de progression
p = int(telechbloc*taillebloc/totalblocs*100)
self.barre.setValue(p)
QtCore.QCoreApplication.processEvents() # force le rafraichissement
else:
# taille maxi inconnue: la barre sera une chenille sans progression
if self.barre.maximum > 0:
self.barre.reset()
self.barre.setRange(0, 0)
#========================================================================
def fintelech(self, msg):
"""Lancé quand le thread se termine (normalement ou pas)"""
QtGui.QMessageBox.information(self,
u"Téléchargement",
msg)
#========================================================================
def stop_m(self):
"""demande l'arrêt du téléchargement avant la fin"""
if self.telech!=None and self.telech.isRunning():
self.telech.stoptelech()
#========================================================================
def closeEvent(self, event):
"""lancé à la fermeture de la fenêtre quelqu'en soit la méthode"""
self.stop_m() # arrête un éventuel téléchargement en cours
event.accept()
#############################################################################
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
fen = Fenetre()
fen.show()
sys.exit(app.exec_()) |
Partager