python - font - tamaño de letra en tkinter
¿Cómo escribir un indicador de progreso de descarga en Python? (9)
Estoy escribiendo una pequeña aplicación para descargar archivos a través de http (como, por ejemplo, se describe here ).
También quiero incluir un pequeño indicador de progreso de descarga que muestre el porcentaje del progreso de la descarga.
Aquí es lo que se me ocurrió:
sys.stdout.write(rem_file + "...") urllib.urlretrieve(rem_file, loc_file, reporthook=dlProgress) def dlProgress(count, blockSize, totalSize): percent = int(count*blockSize*100/totalSize) sys.stdout.write("%2d%%" % percent) sys.stdout.write("/b/b/b") sys.stdout.flush()
Salida: MyFileName ... 9%
¿Alguna otra idea o recomendación para hacer esto?
Una cosa que es algo molesta es el cursor parpadeante en la terminal en el primer dígito del porcentaje. ¿Hay alguna forma de prevenir esto? ¿Hay alguna manera de ocultar el cursor?
EDITAR:
Aquí una mejor alternativa usando una variable global para el nombre de archivo en dlProgress y el código ''/ r'':
global rem_file # global variable to be used in dlProgress urllib.urlretrieve(rem_file, loc_file, reporthook=dlProgress) def dlProgress(count, blockSize, totalSize): percent = int(count*blockSize*100/totalSize) sys.stdout.write("/r" + rem_file + "...%d%%" % percent) sys.stdout.flush()
Salida: MyFileName ... 9%
Y el cursor aparece al final de la línea. Mucho mejor.
Así es como lo hice, esto podría ayudarte: https://github.com/mouuff/MouDownloader/blob/master/api/download.py
Hay una biblioteca de barra de progreso de texto para python en http://pypi.python.org/pypi/progressbar/2.2 que puede serle útil:
Esta biblioteca proporciona una barra de progreso en modo texto. Esto se usa típicamente para mostrar el progreso de una operación de larga ejecución, proporcionando una pista visual de que el procesamiento está en marcha.
La clase ProgressBar gestiona el progreso, y el formato de la línea viene dado por varios widgets. Un widget es un objeto que puede mostrarse de forma diferente según el estado del progreso. Hay tres tipos de artilugios: - una cadena, que siempre se muestra a sí misma; - un ProgressBarWidget, que puede devolver un valor diferente cada vez que se llama a su método de actualización; y - un ProgressBarWidgetHFill, que es como ProgressBarWidget, excepto que se expande para completar el ancho restante de la línea.
El módulo de barra de progreso es muy fácil de usar, pero muy poderoso. Y admite automáticamente características como el cambio de tamaño automático cuando esté disponible.
Para archivos pequeños, puede necesitar tener estas líneas para evitar porcentajes locos:
sys.stdout.write ("/ r% 2d %%"% por ciento)
sys.stdout.flush ()
Aclamaciones
Por lo que vale, aquí está el código que utilicé para que funcione:
from urllib import urlretrieve
from progressbar import ProgressBar, Percentage, Bar
url = "http://......."
fileName = "file"
pbar = ProgressBar(widgets=[Percentage(), Bar()])
urlretrieve(url, fileName, reporthook=dlProgress)
def dlProgress(count, blockSize, totalSize):
pbar.update( int(count * blockSize * 100 / totalSize) )
Si usa el paquete de curses
, tiene un control mucho mayor de la consola. También tiene un costo mayor en complejidad de código y probablemente sea innecesario a menos que esté desarrollando una aplicación grande basada en consola.
Para una solución simple, siempre puede poner la rueda giratoria al final del estado de memoria (la secuencia de caracteres |, /, -, /
que realmente se ve bien debajo del cursor parpadeante).
También puedes probar:
sys.stdout.write("/r%2d%%" % percent)
sys.stdout.flush()
Utilizando un solo retorno de carro al comienzo de su cadena en lugar de varios retrocesos. El cursor seguirá parpadeando, pero parpadeará después del signo de porcentaje en lugar de debajo del primer dígito, y con un carácter de control en lugar de tres, puede obtener menos parpadeo.
Tarde a la fiesta, como de costumbre. Aquí hay una implementación que admite el informe de progreso, como el núcleo urlretrieve
:
import urllib2
def urlretrieve(urllib2_request, filepath, reporthook=None, chunk_size=4096):
req = urllib2.urlopen(urllib2_request)
if reporthook:
# ensure progress method is callable
if hasattr(reporthook, ''__call__''):
reporthook = None
try:
# get response length
total_size = req.info().getheaders(''Content-Length'')[0]
except KeyError:
reporthook = None
data = ''''
num_blocks = 0
with open(filepath, ''w'') as f:
while True:
data = req.read(chunk_size)
num_blocks += 1
if reporthook:
# report progress
reporthook(num_blocks, chunk_size, total_size)
if not data:
break
f.write(data)
# return downloaded length
return len(data)
Usé este código:
url = (<file location>)
file_name = url.split(''/'')[-1]
u = urllib2.urlopen(url)
f = open(file_name, ''wb'')
meta = u.info()
file_size = int(meta.getheaders("Content-Length")[0])
print "Downloading: %s Bytes: %s" % (file_name, file_size)
file_size_dl = 0
block_sz = 8192
while True:
buffer = u.read(block_sz)
if not buffer:
break
file_size_dl += len(buffer)
f.write(buffer)
status = r"%10d [%3.2f%%]" % (file_size_dl, file_size_dl * 100. / file_size)
status = status + chr(8)*(len(status)+1)
print status,
f.close()
def download_progress_hook(count, blockSize, totalSize):
"""A hook to report the progress of a download. This is mostly intended for users with slow internet connections. Reports every 5% change in download progress.
"""
global last_percent_reported
percent = int(count * blockSize * 100 / totalSize)
if last_percent_reported != percent:
if percent % 5 == 0:
sys.stdout.write("%s%%" % percent)
sys.stdout.flush()
else:
sys.stdout.write(".")
sys.stdout.flush()
last_percent_reported = percent
urlretrieve(url, filename, reporthook=download_progress_hook)