拆除主窗口时Python崩溃

时间:2018-10-16 21:53:33

标签: python tkinter python-multithreading

运行以下代码时出现此错误。我知道这是由于主窗口不在主线程中而导致的失败。只是不完全确定如何更改它。

  

Tcl_AsyncDelete:异步处理程序被错误的线程删除

def download(url, filename):
root = progressbar = quit_id = None
ready = Event()

def reporthook(blocknum, blocksize, totalsize):
    nonlocal quit_id
    if blocknum == 0:  # started downloading
        def guiloop():
            nonlocal root, progressbar
            root = Tk()
            root.withdraw()  # hide
            progressbar = ttk.Progressbar(root, length=400)
            progressbar.grid()
            # show progress bar if the download takes more than .5 seconds
            root.after(500, root.deiconify)
            ready.set()  # gui is ready
            root.mainloop()

        Thread(target=guiloop).start()
    ready.wait(1)  # wait until gui is ready
    percent = blocknum * blocksize * 1e2 / totalsize  # assume totalsize > 0
    if quit_id is None:
        root.title('%%%.0f %s' % (percent, filename,))
        progressbar['value'] = percent  # report progress
        if percent >= 100:  # finishing download
            quit_id = root.after(0, root.destroy)  # close GUI
return urlretrieve(url, filename, reporthook)

1 个答案:

答案 0 :(得分:0)

import sys
from threading import Event, Thread
from tkinter import Tk, ttk
from urllib.request import urlretrieve

def download(url, filename):
    root = progressbar = quit_id = None
    ready = Event()
  

def on_closing():               root.destroy()

    def reporthook(blocknum, blocksize, totalsize):
        nonlocal quit_id
        if blocknum == 0: # started downloading
            def guiloop():
                nonlocal root, progressbar
                root = Tk()
                root.withdraw()  # hide
                progressbar = ttk.Progressbar(root, length=400)
                progressbar.grid()

                # show progress bar if the download takes more than .5 seconds
                root.after(500, root.deiconify)
                ready.set() # gui is ready
                root.mainloop()
            Thread(target=guiloop).start()
        ready.wait(1) # wait until gui is ready
        percent = blocknum * blocksize * 1e2 / totalsize # assume totalsize > 0
        if quit_id is None:
            root.title('%%%.0f %s' % (percent, filename,))
            progressbar['value'] = percent # report progress
            if percent >= 100:  # finishing download
  

quit_id = root.after(0,root.protocol(“ WM_DELETE_WINDOW”,   on_closing()))#关闭GUI

    return urlretrieve(url, filename, reporthook)