所以我在Python中创建了一个应用程序,通过单击界面上的按钮从Internet下载文件。用户还必须在下载之前命名文件。正在下载的文件是Microsoft病毒定义(因为它是一个大文件)。我有一个进度条来显示下载的进度,但我遇到了两个问题之一:
这是我尝试的一种方法,当我点击按钮时,文件会下载,但进度条会立即显示它已完成。这是代码:
def download():
link = "http://go.microsoft.com/fwlink/?LinkID=87341"
filename = "C:/My Python Apps/" + txtName.get() +".exe"
r = requests.get(link, stream=True)
f = open(filename, "wb")
fileSize = int(r.headers["Content-Length"])
chunk = 1
chunkSize = 1024
bars = int(fileSize/chunkSize)
print(dict(num_bars=bars))
with open(filename, "wb") as fp:
for chunk in tqdm(r.iter_content(chunk_size=chunkSize), total=bars, unit="KB",
desc=filename, leave=True):
fp.write(chunk)
progress["value"] = fileSize
return
我尝试的另一种方法效果更好,因为下载开始时,它不会立即射到栏的末尾。但问题是在下载甚至达到1%之前,即使文件仍在下载,该栏已经进展到完成。以下是此功能的代码:
link = "http://go.microsoft.com/fwlink/?LinkID=87341"
filename = "C:/My Python Apps/" + txtName.get() +".exe"
r = requests.get(link, stream=True)
totalSize = int(r.headers.get("content-length", 0))
with open(filename, "wb") as f:
i = 0
for data in tqdm(r.iter_content(32*1024), total=totalSize, unit="B", unit_scale=True):
f.write(data)
progress["value"] = i
i += 1
return
如何准确正确地获取进度条以指示下载进度?
如果有帮助,这是我的应用程序的完整代码:
from threading import Thread
from tkinter import *
from tkinter import Tk, ttk
def downloadThread():
Thread(target=download).start()
def download():
# Place either of the functions in the question here...
root = Tk()
w = 400
h = 135
ws = root.winfo_screenwidth()
wh = root.winfo_screenheight()
x = (ws / 2) - (w / 2)
y = (wh / 2) - (h / 2)
root.geometry("%dx%d+%d+%d" % (w, h, x, y))
root.title("MyApp beta")
lblName = Label(root, text="File name: ")
lblName.place(x=5, y=5)
txtName = Entry(root, width=25)
txtName.place(x=5, y=25)
value = IntVar()
progress = ttk.Progressbar(root, length=155)
progress.place(x=5, y=50)
btnDownload = Button(root, text="Download Definition", width=21,
command=lambda: downloadThread())
btnDownload.place(x=5, y=100)
lblLoad = Label(root, text="Downloading, please wait...")
lblLoad.place_forget()
root.mainloop()
答案 0 :(得分:1)
在第一个实现中,您可以立即将进度条的值设置为完整文件大小。你想要的是使它成为文件大小的一小部分(已经下载的那个)。
这有效:
def download():
link = "http://go.microsoft.com/fwlink/?LinkID=87341"
filename = "C:/My Python Apps/" + txtName.get() +".exe"
r = requests.get(link, stream=True)
f = open(filename, "wb")
fileSize = int(r.headers["Content-Length"])
chunk = 1
downloaded = 0 # keep track of size downloaded so far
chunkSize = 1024
bars = int(fileSize/chunkSize)
print(dict(num_bars=bars))
with open(filename, "wb") as fp:
for chunk in tqdm(r.iter_content(chunk_size=chunkSize), total=bars, unit="KB",
desc=filename, leave=True):
fp.write(chunk)
downloaded += chunkSize # increment the downloaded
progress["value"] = (downloaded*100/fileSize)#*100 #Default max value of tkinter progress is 100
return
顺便说一下,你没有导入tqdm
:花了很多时间来弄清楚那是什么。