【问题标题】:Tkinter application does not close on root.destroy()Tkinter 应用程序不会在 root.destroy() 上关闭
【发布时间】:2021-12-15 15:17:39
【问题描述】:

我一直在开发一个 tkinter 应用程序,用于从 Internet 下载文件并在进度条 (Progressbar) 上显示文件的进度。

由于下载过程与 GUI 不同(并且由于 tkinter 在无限循环上运行 GUI 主线程),我想为下载过程创建一个不同的线程来继续,它会更新进度后台显示栏

然后我会继续等待后台进程结束,并调用 root.destroy() 方法来结束应用程序,但是在手动关闭应用程序时应用程序没有关闭 - 它会返回以下内容错误

_tkinter.TclError:无法调用“destroy”命令:应用程序已被销毁

这里是代码

class download:

    #Initializing the root
    def __init__(self):
        self.root = Tk()

    #creating the progress bar and packing it to the root
    def create_progress_bar(self):
        self.progress_bar = Progressbar(self.root, orient = HORIZONTAL, length = 200, mode = 'determinate')
        self.progress_bar.pack(pady=10)
        
    #function to start the mainloop
    def start_application(self):    
        self.root.mainloop()

    #updating the progress bar from the background thread
    def update_progress(self, count, blocksize, totalsize):
        update = int(count * blocksize * 100 / totalsize)
        self.progress_bar['value'] = update
        self.root.update_idletasks()

    #downloading the file from the background thread
    def download_file(self, download_url):
        #using the reporthook to get information about download progress
        urllib.request.urlretrieve(download_url, 'a.jpg', reporthook=self.update_progress)

    #closing the root function
    def close(self):
        self.root.destroy()        

    #handling the download
    def handle_download(self, download_url):
        #creating a different thread
        self.process = Thread(target=self.download_file, args=(download_url,))
        #creating the progress bar
        self.create_progress_bar()
        #starting the background thread
        self.process.start()
        #starting the GUI
        self.start_application()
        #waiting for the background thread to end
        self.process.join()
        #closing the application
        self.close()

ob = download()
ob.handle_download('link')

不管怎样,我确实尝试让事情发生在同一个线程上,但应用程序无法响应更新。 任何关于此事的见解都将非常受欢迎。

【问题讨论】:

  • self.root.quit()(我认为),我也建议继承自Tk
  • 如果需要关闭应用,使用exit()sys.exit(0)
  • @Matiiss 我已经尝试过这样做,但这并没有关闭应用程序。
  • 你需要提供一个minimal reproducible example(同样每个 PEP 8 的类名应该在 CapitalCase 中)并彻底解释这个问题
  • @Armali 哦,谢谢,我无法确定我的程序没有达到破坏方法。谢谢你也解决了我的问题!

标签: python multithreading tkinter


【解决方案1】:

由于您的程序仅在self.root.mainloop() 返回后才执行self.root.destroy(),因此除非您手动关闭应用程序,否则它不会达到破坏点,然后调用@987654323 毫无意义@。

您可以不时检查下载线程是否正在运行,如果没有,则销毁窗口。

    def watch(self):
        if self.process.is_alive(): self.root.after(500, self.watch)
        else: self.close()

    #handling the download
    def handle_download(self, download_url):
…
        #starting the background thread
        self.process.start()
        self.watch()
…
        #closing the application
        #self.close() is too late here

【讨论】:

  • 非常感谢!!观察完成的过程是有效的。再次感谢您!
猜你喜欢
  • 2014-06-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-10-24
  • 1970-01-01
  • 2019-01-08
  • 1970-01-01
相关资源
最近更新 更多