使用进度条调用运行urllib2崩溃程序

时间:2014-07-20 18:52:44

标签: python download tkinter progress-bar ttk

嗨,所以我的代码有问题(可能不是urllib2本身),但它不会创建进度条和崩溃。但是在等待代码完成后下载我的文件。无论如何我可以防止挂起并可能将下载分解为更小的块,因为我对python的经验很少...我的代码如下:

def iPod1():
pb = ttk.Progressbar(orient ="horizontal",length = 200, mode ="indeterminate")
pb.pack(side="top") 
pb.start()
download = "http://downloads.sourceforge.net/project/whited00r/7.1/Whited00r71-iPodTouch1G.zip?r=http%3A%2F%2Fsourceforge.net%2Fprojects%2Fwhited00r%2Ffiles%2F7.1%2F&ts=1405674672&use_mirror=softlayer-ams"
request = urllib2.urlopen( download)
pb.start()
output = open("Whited00r71-iPodTouch1G.zip", "wb")
output.write(request.read())
output.close()
pb.stop
tkMessageBox.showinfo(title="Done", message="Download complete. Please follow the installation instructions provided in the .html file.")   

1 个答案:

答案 0 :(得分:0)

通过将下载移动到自己的线程中,可以避免挂起/冻结GUI。由于不能从运行Tk主循环的其他线程更改GUI,因此我们必须定期检查下载线程是否已完成。这通常通过在窗口小部件对象上使用after()方法重复调度延迟函数调用来完成。

在将文件写入本地文件之前,不能将整个文件读入内存可以使用shutil.copyfileobj()完成。

import shutil
import tkMessageBox
import ttk
import urllib2
from threading import Thread

IPOD_1_URL = (
    'http://downloads.sourceforge.net/project/whited00r/7.1/'
    'Whited00r71-iPodTouch1G.zip'
    '?r=http%3A%2F%2Fsourceforge.net%2Fprojects%2Fwhited00r%2Ffiles%2F7.1%2F'
    '&ts=1405674672'
    '&use_mirror=softlayer-ams'
)


def download(url, filename):
    response = urllib2.urlopen(url)
    with open(filename, 'wb') as output_file:
        shutil.copyfileobj(response, output_file)


def check_download(thread, progress_bar):
    if thread.is_alive():
        progress_bar.after(500, check_download, thread, progress_bar)
    else:
        progress_bar.stop()
        tkMessageBox.showinfo(
            title='Done',
            message='Download complete. Please follow the installation'
                ' instructions provided in the .html file.'
        )


def start_download_for_ipod1():
    progress_bar = ttk.Progressbar(
        orient='horizontal', length=200, mode='indeterminate'
    )
    progress_bar.pack(side='top')
    progress_bar.start()
    thread = Thread(
        target=download, args=(IPOD_1_URL, 'Whited00r71-iPodTouch1G.zip')
    )
    thread.daemon = True
    thread.start()
    check_download(thread, progress_bar)