En este capítulo del tutorial de Python 3 más PyQt5, veremos como trabajar con objetos Progress Bar (Barra de progreso) que pertenecen a la clase QProgressBar, concretamente veremos como crear una aplicación que nos permita descargar archivos de servidores remotos con la ayuda del módulo QtNetwork que nos proporciona una serie de clases que serán de gran ayuda para ir controlando el proceso de descarga e ir viendo en el Progress Bar el progreso de la misma, todo ello gracias a una serie de señales (eventos) y métodos predefinidos.
Crear un cuadro de diálogo en Designer y agregar los siguiente objetos:
- Un objeto Label con el texto "Ruta del archivo a descargar:"
- Un objeto Line Edit con el nombre ruta
- Un objeto Progress Bar con el nombre progressBar
- Un objeto Push Button con el texto "Descargar" y el nombre btn_download
- Un objeto Push Button con el texto "Cancelar" y el nombre btn_cancel
- Un objeto Label con el nombre labelState y sin texto
- Guardar el archivo como progressbar.ui
progressbar.ui
import sys
from PyQt5.QtWidgets import QApplication, QDialog
from PyQt5 import uic
from PyQt5.QtCore import QUrl, QFileInfo, QFile, QIODevice
from PyQt5.QtNetwork import QNetworkAccessManager, QNetworkRequest
class Dialogo(QDialog):
def __init__(self):
QDialog.__init__(self)
uic.loadUi("progressbar.ui", self)
#Almacena la url del archivo a descargar
self.url = None
#Almacena el manejador del fichero a crear
self.file = None
#almacena el nombre del archivo a descargar
self.filename = None
#almacena en su caso el error en un string
self.errorString = None
#almacena en su caso el número de error
self.errorCode = None
#Objeto para establecer la conexión y crear el objeto QNetworkReply
self.http = QNetworkAccessManager(self)
#Desactivar los botones de descargar y cancelar en un principio
self.btn_download.setEnabled(False)
self.btn_cancel.setEnabled(False)
#Establece si los botones están activos o no
self.btn_active = False
#Inicia todo el proceso de descarga
self.btn_download.clicked.connect(self.download)
#Cancela la descarga
self.btn_cancel.clicked.connect(self.cancel_download)
#Detectar el cambio de texto en el campo de texto para activar el botón de descarga
self.ruta.textChanged.connect(self.btn_enabled)
#Detectar el cambio de texto en el campo de texto para activar el botón de descarga
def btn_enabled(self):
if self.ruta.text() != "":
self.btn_active = True
self.btn_download.setEnabled(True)
else:
self.btn_active = False
#Inicia todo el proceso de descarga
def download(self):
if self.btn_active == True:
#Ruta indicada por el usuario
ruta = self.ruta.text()
self.url = QUrl(ruta)
fileinfo = QFileInfo(self.url.path())
self.filename = fileinfo.fileName()
#Manejador del fichero
self.file = QFile(self.filename)
#Si no es posible crear el fichero
if not self.file.open(QIODevice.WriteOnly):
self.labelState.setText("No se pudo crear el archivo")
self.file.close()
else: #Entonces llamar al método que inicia la descarga del archivo
self.start_download()
#Inicia el proceso de descarga y controla las diferente señales (eventos) durante la misma
def start_download(self):
#Objeto QNetworkReply
self.reply = self.http.get(QNetworkRequest(self.url))
self.labelState.setText("Iniciando la descarga ...")
#Empieza la lectura del archivo remoto y escritura local
self.reply.readyRead.connect(self.ready_read)
#Señal predefinida para obtener los bytes en el proceso descarga y asignarlos al progressBar
self.reply.downloadProgress.connect(self.updateDataReadProgress)
#Señal para capturar posibles errores durante la descarga
self.reply.error.connect(self.error_download)
#Finalización de la descarga
self.reply.finished.connect(self.finished_download)
#Ocurre durante la escritura del archivo
def ready_read(self):
#Escritura del archivo local
self.file.write(self.reply.readAll())
self.labelState.setText("Descargando ...")
#Activación del botón de cancelar
self.btn_cancel.setEnabled(True)
#Método predefinido en la clase QNetworkReply para leer el progreso de descarga
def updateDataReadProgress(self, bytesRead, totalBytes):
self.progressBar.setMaximum(totalBytes)
self.progressBar.setValue(bytesRead)
#Si ha ocurrido algún error durante el proceso de descarga
def error_download(self, error):
#Si ha ocurrido un error, mostrar el error e eliminar el archivo en el método finished_download
self.errorString = self.reply.errorString()
self.errorCode = error
#Ocurre cuando la descarga ha finalizado
def finished_download(self):
#Si existe un error
if self.errorCode is not None:
#Poner a 0 el progressBar
self.progressBar.setValue(0)
self.labelState.setText(str(self.errorCode) + ": " + self.errorString)
#Eliminar el archivo
self.file.remove()
else:
self.labelState.setText("Descarga completada")
#Cerrar el fichero
self.file.close()
#Desactivar el botón de cancelar ya que la descarga ha finalizado
self.btn_cancel.setEnabled(False)
#Restaurar a None los valores de los atributos de error
self.errorString = None
self.errorCode = None
#Cancelar la descargar durante su ejecución
def cancel_download(self):
#Abortar la descarga
self.reply.abort()
#Desconectar del servidor
self.reply.close()
#Eliminar el fichero
self.file.remove()
#Cerrar el fichero
self.file.close()
app = QApplication(sys.argv)
dialogo = Dialogo()
dialogo.show()
app.exec_()

No hay comentarios:
Publicar un comentario