Code: Alles auswählen
class Download_Thread(QThread):
finished_thread = pyqtSignal()
notify_progress = pyqtSignal(int)
def __init__(self, loc, link):
QThread.__init__(self)
self.url = link
self.location = loc
self._run_semaphore = QSemaphore(1)
def run(self):
print self.url
print self.location
file = requests.get(self.url, stream=True)
file_size = int(requests.head(self.url).headers.get('content-length', [0]))
print "%s Byte" %file_size
result = file_size / (1024*5)
print result
chunk_size = int(result)
downloaded_bytes = 0
with open(self.location, 'wb') as fd:
for chunk in file.iter_content(chunk_size):
fd.write(chunk)
downloaded_bytes = fd.tell() # sehr genau und direkt
print (float(downloaded_bytes)/file_size*100)
self.notify_progress.emit(float(downloaded_bytes)/file_size*100)
if self._run_semaphore.available() == 0:
self._run_semaphore.release(1)
break
print "Finish"
self.finished_thread.emit()
def stop(self):
print "Cancel"
self.finished_thread.emit()
self._run_semaphore.acquire(1)
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MyCustomDialog()
window.resize(600, 400)
window.show()
sys.exit(app.exec_())
Zeile 11: Laut der QT-Dokumentation is die QSemaphore()-Klasse thread-sicher. Diese Klasse dient also zur allgemeinen Zählung. Dadurch werden bestimmte Anzahlen von Ressourcen zur Verfügung gestellt. Also wird QSemaphore an das Attribut self._run_semaphore gebunden.
Zeile 30 bis 32: Je jedem Schleifendurchlauf wird durch die If-Kaskade mittels der available()-Methode abgefragt, ob die Ressource noch zur Verfügung steht. Wenn nicht, dann wird durch die release()-Method die Ressource wieder zur Verfügung gestellt, und im Anschluss mit einem break der Verlauf abgebrochen. Die release()-Methode dient dazu, dass man zu einem späteren Zeitpunkt den Thread nochmal starten kann.
Zeile 40: In der stop()-Funktion wird die Ressource durch die acquire()-Methode die Ressource "erworben", und dadurch wie der Verlauf in der run()-Funktion unterbrochen.
Das wäre mein Verständnis.