Instantly share code, notes, and snippets.
Save flyfire/ab61451cc6e42d0b19921f5d4430bf1c to your computer and use it in GitHub Desktop.
A class for asynchronous url loading using Qt, PyQt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.Learn more about bidirectional Unicode characters
''' | |
Copyright 2014 Lloyd Konneker | |
Release under the GPLv3 | |
''' | |
fromPyQt5.QtCoreimportpyqtSignalasSignal | |
fromPyQt5.QtCoreimportQObject,QByteArray,QUrl | |
fromPyQt5.QtNetworkimportQNetworkAccessManager,QNetworkRequest | |
classDownLoader(QObject): | |
''' | |
Asynchronous download from network, which is expected to be unreliable and possibly slow. | |
A thin wrapper around QNetworkAccessManager() | |
Qt docs: 'One QNetworkAccessManager should be enough for the whole Qt application.' | |
Similarly, one DownLoader might be enought for the whole app. | |
It is untested what happens when you create more than one. | |
Usage: | |
foo = Downloader(url) | |
foo.downloaded.connect(clientLoader) | |
foo.doDownload(QUrl('http:/...')) | |
# execution continues, clientLoader slot will receive signal | |
def clientLoader(): | |
bar = foo.downloadedData() | |
# bar is only a reference, consume it before calling doDownload() again | |
''' | |
downloaded=Signal() | |
def__init__(self):# parent not used | |
super(DownLoader,self).__init__()# !!! init QObject | |
# private | |
self._webController=QNetworkAccessManager() | |
self._downloadedData=None | |
# connect asynchronous result, when a request finishes | |
self._webController.finished.connect(self._fileDownloaded) | |
# private slot, no need to declare as slot | |
def_fileDownloaded(self,reply): | |
''' | |
Handle signal 'finished'. A network request has finished. | |
''' | |
self._downloadedData=reply.readAll() | |
# prior _downloadedData is now garbage collectable | |
assertisinstance(self._downloadedData,QByteArray) | |
reply.deleteLater()# schedule for delete from main event loop | |
# print("emitted") | |
self.downloaded.emit() | |
''' | |
Public API | |
''' | |
defdoDownload(self,url): | |
assertisinstance(url,QUrl) | |
request=QNetworkRequest(url) | |
self._webController.get(request) | |
# asynchronous, does not wait, execution continues | |
defdownloadedData(self): | |
''' | |
QByteArray that was downloaded. | |
Call this only after receiving signal 'downloaded'. | |
Copy result before calling doDownload() again. | |
''' | |
returnself._downloadedData | |
Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment