Python跨文件调用传参及customtkinter GUI关闭报错问题
问题解决:跨文件调用CustomTkinter Textbox打印与关闭GUI报错
问题1:跨文件调用print_SM函数无效果
原因分析
File2中from File1 import App后创建了新的App实例,但这个实例并非当前运行的GUI窗口实例,调用它的print_SM只会在隐藏的实例上操作,自然看不到效果。同时这种写法还会引发循环导入问题(File1导入File2,File2导入File1)。
解决方案
不要在File2中创建新的App实例,而是将当前运行的App实例传递给File2的函数。修改步骤如下:
- 修改File1的
stop_execution方法,把当前实例传入stop_exec:
def stop_execution(self): from File2 import stop_exec stop_exec(self) # 传入当前App实例
- 修改File2的代码,移除多余的实例创建,让
stop_exec接收传入的实例:
# 不需要再导入App和创建实例 def stop_exec(app_instance): y = "test print" app_instance.print_SM(y)
这样点击按钮时,就会调用当前运行的GUI实例的print_SM,Textbox就能正常显示文本了。
问题2:关闭GUI后出现"invalid command name"报错
原因分析
CustomTkinter内部会使用Tkinter的after方法定时执行一些任务(比如DPI缩放检查、界面更新),当你关闭GUI窗口后,这些after任务还在队列中,尝试调用已经销毁的窗口对象的命令,就会抛出这类错误。
解决方案
在App类中重写destroy方法,清理所有未完成的after任务,然后再销毁窗口:
修改File1的App类,添加destroy方法:
class App(ctk.CTk): def __init__(self): super().__init__() # 原初始化代码不变 ... # 存储after任务的ID,方便后续清理 self.after_ids = [] # 其他方法不变... def destroy(self): # 取消所有pending的after任务 for id in self.after_ids: self.after_cancel(id) # 处理CustomTkinter内部残留的after任务 try: super().destroy() except tk.TclError: pass
最终完整代码
File1.py
import customtkinter as ctk import tkinter as tk class App(ctk.CTk): def __init__(self): super().__init__() self.title("dummy") self.geometry(f"{800}x{500}") self.SM_data = ctk.CTkTextbox(self, corner_radius=0, fg_color="#dee2e6", text_color="#000000",font=("Tahoma",12), border_width=1, border_color="#000000") self.SM_data.grid(row=0, column=0, sticky="nsew") self.stop_button =ctk.CTkButton(self, width=24, height=24, text="X", anchor="right", hover_color="#D20103", fg_color="#E60808", command= self.stop_execution) self.stop_button.grid(row=0, column=1, padx=(0,4), sticky="e") # 存储after任务ID self.after_ids = [] def print_SM(self, text): print(f"Received text: {text}") self.SM_data.insert(tk.END, text + "\n") def stop_execution(self): from File2 import stop_exec stop_exec(self) def destroy(self): # 清理所有after任务 for task_id in self.after_ids: self.after_cancel(task_id) # 处理CustomTkinter内部的after任务残留 try: super().destroy() except tk.TclError: pass if __name__=="__main__": app = App() app.mainloop()
File2.py
def stop_exec(app_instance): y = "test print" app_instance.print_SM(y)
这样修改后,点击按钮就能在Textbox中显示"test print",关闭GUI也不会再出现报错。
内容的提问来源于stack exchange,提问作者Muhammad Rusydi Rasin
相关产品推荐
相关产品推荐

