You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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的函数。修改步骤如下:

  1. 修改File1的stop_execution方法,把当前实例传入stop_exec:
def stop_execution(self):
    from File2 import stop_exec
    stop_exec(self)  # 传入当前App实例
  1. 修改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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 18:45:12