如何创建相互独立的tkinter窗口,关闭调用窗口时避免控制台报错
问题根因
你当前的代码同时创建了两个Tk主实例,且在第一个MainWindow实例的初始化方法中直接销毁自身,此时tkinter内部事件队列中仍存在针对该已销毁实例的待处理事件(如ttk主题变更回调),调用已销毁实例的接口就抛出了对应警告。
另外单进程内的多个Tk实例共享底层tcl解释器,任意一个实例崩溃都会导致整个程序退出,无法实现完全独立的运行效果。
解决方案
方案1:单进程下消除警告
调整旧窗口的销毁时机,等新窗口初始化完成、旧窗口的待处理事件全部处理完成后再销毁旧窗口,修改后代码如下:
import tkinter class MainWindow(tkinter.Tk): def __init__(self, condition): super().__init__() self.title("Main Window ") self.geometry("640x360") if condition == 1: self.dashboard = DashboardWindow() # 延迟执行销毁,等待事件队列清空 self.after(10, self.safe_destroy) def safe_destroy(self): # 先处理完当前窗口所有待处理事件 self.update() self.destroy() class DashboardWindow(tkinter.Tk): def __init__(self): super().__init__() self.title("Dashboard Window") self.geometry("940x560") if __name__ == "__main__": app = MainWindow(1) app.mainloop()
该方案仅消除警告,未实现窗口完全独立,单进程内任意窗口崩溃会导致所有窗口退出
方案2:完全独立的多进程实现
将每个窗口放在独立进程中运行,进程之间资源完全隔离,任意窗口关闭、崩溃都不会影响其他窗口,完全符合独立运行的要求,代码如下:
import tkinter import multiprocessing def run_dashboard(): class DashboardWindow(tkinter.Tk): def __init__(self): super().__init__() self.title("Dashboard Window") self.geometry("940x560") app = DashboardWindow() app.mainloop() class MainWindow(tkinter.Tk): def __init__(self, condition): super().__init__() self.title("Main Window ") self.geometry("640x360") if condition == 1: # 启动非守护进程运行仪表盘窗口,主进程退出不影响子进程 dashboard_process = multiprocessing.Process(target=run_dashboard, daemon=False) dashboard_process.start() self.destroy() if __name__ == "__main__": app = MainWindow(1) app.mainloop()
注意Windows系统下多进程代码必须写在if __name__ == "__main__"入口下,否则会出现进程启动异常
内容的提问来源于stack exchange,提问作者david stephen
相关产品推荐
相关产品推荐

