Skip to content

Instantly share code, notes, and snippets.

@abdalla-alothman
Created February 28, 2014 12:35
Show Gist options
  • Save abdalla-alothman/9270322 to your computer and use it in GitHub Desktop.
Save abdalla-alothman/9270322 to your computer and use it in GitHub Desktop.
Simple PyQt Progress Bar Downloader
#!/usr/bin/python3
# This is downloading class which uses python 3 with PyQt4. It shows how to use the
# QT progress bar in python. The downloading takes place in the UrlDownloader class
# which inherits from QThread.
#
# To test the widget:
# 1. try copying a URL that points to a large file.
# 2. Paste the file url into the combobox's text area, but do nothing more.
# 3. Copy another URL pointing to a large file.
# 4. Hit enter or the "Download" button.
# 5. Immediately clear the text field and enter the other URL.
#
# The status is displayed on the progress bar itself, in addition to a label on
# the console.
#
# Abdalla S. Alothman
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from progbarDownloaderWG import *
import sys, urllib.request
class ProgBarDownloader(QtGui.QWidget, Ui_ProgBarDownloader):
def __init__(self, parent=None):
QWidget.__init__(self, parent)
self.ui = Ui_ProgBarDownloader()
self.ui.setupUi(self)
self.downloader = UrlDownloader()
self.uList = list()
self.ui.urlEdit.activated.connect(lambda: self.updateList(self.ui.urlEdit.currentText()))
self.ui.startButton.clicked.connect(lambda: self.updateList(self.ui.urlEdit.currentText()))
self.ui.urlEdit.activated.connect(lambda: self.download(self.ui.urlEdit.currentText()))
self.ui.startButton.clicked.connect(lambda: self.download(self.ui.urlEdit.currentText()))
self.downloader.progSig.connect(self.ui.progressBar.setValue)
self.downloader.progStat[str].connect(self.ui.label.setText)
self.downloader.doneSig.connect(self.ui.progressBar.reset)
self.downloader.doneSig.connect(lambda: self.ui.label.setText(self.ui.label.text().replace("Saving", "Saved") + " - <b>Download Complete</b>."))
self.downloader.sendNext[str].connect(self.clearLastUrl)
self.downloader.doneSig.connect(self.ui.urlEdit.clearEditText)
self.downloader.doneSig.connect(self.checkUList)
def clearLastUrl(self, url):
self.uList.remove(url)
@pyqtSlot()
def updateList(self, url):
if not url in self.uList:
self.uList.append(url)
@pyqtSlot()
def checkUList(self):
if self.uList:
self.ui.label.clear()
for u in self.uList:
_url = u
self.download(_url)
@pyqtSlot()
def download(self, Url=str()):
if Url is "" or not Url.startswith("http://"):
return
self.downloader.setUrl(Url)
self.downloader.start()
class UrlDownloader(QThread):
doneSig = pyqtSignal()
progSig = pyqtSignal(int)
progStat = pyqtSignal(str)
sendNext = pyqtSignal(str)
def __init__(self, parent=None):
super(UrlDownloader, self).__init__(parent)
self.url0 = str("")
def setUrl(self, u):
self.url0 = u
def run(self):
url = self.url0
print("Downloading from: {}".format(url))
rq = urllib.request.urlopen(url)
fSize = int(rq.info()['Content-Length'])
fileName = url.split("/")[-1]
downloadedChunk = 0
blockSize = 2048
with open(fileName, "wb") as sura:
while True:
chunk = rq.read(blockSize)
if not chunk:
print("\nDownload Complete.")
self.sendNext.emit(url)
break
downloadedChunk += len(chunk)
sura.write(chunk)
progress = float(downloadedChunk) / fSize
self.progSig.emit(progress * 100)
stat = r" Saving: {0} [{1:.2%}] of {2} bytes.".format(downloadedChunk, progress, fSize)
stat2 = "<b>Saving {0}</b>: {1} [{2:.2%}] <b>of</b> {3} <b>bytes</b>.".format(fileName, downloadedChunk, progress, fSize)
self.progStat.emit(stat2)
stat = stat + chr(8) * (len(stat) + 1)
sys.stdout.write(stat)
sys.stdout.flush()
self.doneSig.emit()
if __name__ == "__main__":
import sys
a = QApplication(sys.argv)
progTester = ProgBarDownloader()
progTester.show()
sys.exit(a.exec_())
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'progbarDownloader.ui'
#
# Created by: PyQt4 UI code generator 4.9.6
#
# WARNING! All changes made in this file will be lost!
from PyQt4 import QtCore, QtGui
try:
_fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
def _fromUtf8(s):
return s
try:
_encoding = QtGui.QApplication.UnicodeUTF8
def _translate(context, text, disambig):
return QtGui.QApplication.translate(context, text, disambig, _encoding)
except AttributeError:
def _translate(context, text, disambig):
return QtGui.QApplication.translate(context, text, disambig)
class Ui_ProgBarDownloader(object):
def setupUi(self, ProgBarDownloader):
ProgBarDownloader.setObjectName(_fromUtf8("ProgBarDownloader"))
ProgBarDownloader.resize(547, 96)
self.gridLayout = QtGui.QGridLayout(ProgBarDownloader)
self.gridLayout.setObjectName(_fromUtf8("gridLayout"))
self.verticalLayout_2 = QtGui.QVBoxLayout()
self.verticalLayout_2.setObjectName(_fromUtf8("verticalLayout_2"))
self.horizontalLayout = QtGui.QHBoxLayout()
self.horizontalLayout.setObjectName(_fromUtf8("horizontalLayout"))
self.quitButton = QtGui.QPushButton(ProgBarDownloader)
self.quitButton.setEnabled(True)
self.quitButton.setObjectName(_fromUtf8("quitButton"))
self.horizontalLayout.addWidget(self.quitButton)
self.startButton = QtGui.QPushButton(ProgBarDownloader)
self.startButton.setObjectName(_fromUtf8("startButton"))
self.horizontalLayout.addWidget(self.startButton)
self.urlEdit = QtGui.QComboBox(ProgBarDownloader)
self.urlEdit.setMinimumSize(QtCore.QSize(350, 0))
self.urlEdit.setEditable(True)
self.urlEdit.setObjectName(_fromUtf8("urlEdit"))
self.horizontalLayout.addWidget(self.urlEdit)
self.verticalLayout_2.addLayout(self.horizontalLayout)
self.verticalLayout = QtGui.QVBoxLayout()
self.verticalLayout.setObjectName(_fromUtf8("verticalLayout"))
self.label = QtGui.QLabel(ProgBarDownloader)
self.label.setMinimumSize(QtCore.QSize(0, 25))
font = QtGui.QFont()
font.setPointSize(11)
font.setBold(False)
font.setWeight(50)
self.label.setFont(font)
self.label.setStyleSheet(_fromUtf8("background-color: rgb(50, 50, 50); color:rgb(204, 204, 255);"))
self.label.setFrameShape(QtGui.QFrame.Box)
self.label.setFrameShadow(QtGui.QFrame.Plain)
self.label.setText(_fromUtf8(""))
self.label.setAlignment(QtCore.Qt.AlignCenter)
self.label.setObjectName(_fromUtf8("label"))
self.verticalLayout.addWidget(self.label)
self.progressBar = QtGui.QProgressBar(ProgBarDownloader)
self.progressBar.setProperty("value", 0)
self.progressBar.setObjectName(_fromUtf8("progressBar"))
self.verticalLayout.addWidget(self.progressBar)
self.verticalLayout_2.addLayout(self.verticalLayout)
self.gridLayout.addLayout(self.verticalLayout_2, 0, 0, 1, 1)
self.retranslateUi(ProgBarDownloader)
QtCore.QObject.connect(self.urlEdit, QtCore.SIGNAL(_fromUtf8("currentIndexChanged(QString)")), self.urlEdit.setEditText)
QtCore.QObject.connect(self.quitButton, QtCore.SIGNAL(_fromUtf8("clicked()")), ProgBarDownloader.close)
QtCore.QMetaObject.connectSlotsByName(ProgBarDownloader)
def retranslateUi(self, ProgBarDownloader):
ProgBarDownloader.setWindowTitle(_translate("ProgBarDownloader", "Simple Progress Downloader", None))
self.quitButton.setText(_translate("ProgBarDownloader", "Quit", None))
self.startButton.setText(_translate("ProgBarDownloader", "Download", None))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment