Сбой Python при срыве главного окна - PullRequest
0 голосов
/ 17 октября 2018

Я получаю эту ошибку при запуске приведенного ниже кода.Я понимаю, что это терпит неудачу из-за разрушения главного окна, не находящегося в главном потоке.Просто не совсем уверен, как это изменить.

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 голосов
/ 18 октября 2018
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)
...