_tkinter.TclError: invalid command name ".!label.!text" 原因及方法

发布时间 2023-09-11 11:49:48作者: 能跑就行_NPJX

文本框对象报错 _tkinter.TclError: invalid command name ".!label.!text"

具体背景:创建txt文本框,用for循环去创建文本框,然后全局变量接受文本框对象,重复进入界面后就出现错误提示

提示对象名无效,回去翻看代码得出原因,下列是源代码

text_boxes = []  # 外部数组用于存储文本框对象

def btn_click(btn_num):
    # 转换为大写
    content = str(text_boxes[btn_num].get("1.0", tk.END+"-1c"))  # 获取文本框内容的起始位置为1.0到末尾(END)

    if (btn_num == 0):
        text_box_update(1, content.encode("utf-8"))
        text_box_update(2, content.encode("unicode_escape"))
        text_box_update(3, content.encode("gb2312"))

def encode_transform(frame):
    
    labels = ["字符串:", "UTF-8:", "Unicode:", "GB2312:"]
    btn_labels = ["转为编码", "转为字符串", "转为字符串", "转为字符串"]

    button_bg = "#D4D4D4"  # 按钮的背景色
    button_fg = "#000000"  # 按钮的前景色

    for i in range(0, 4):
        # 标签
        label = tk.Label(frame,
                         text=labels[i],
                         font=("Microsoft YaHei", 12),
                         anchor=tk.W)
        label.grid(row=i, column=0, padx=5, pady=5, sticky=tk.W)

        # 创建文本框
        text_box = tk.Text(frame, 
                           font=("Microsoft YaHei", 12), 
                           width=40, 
                           height=8)
        text_box.grid(row=i, column=1, padx=5, pady=5, sticky=tk.NSEW)

        text_boxes.append(text_box)  # 将文本框对象添加到外部数组中
        print(f"Text box: {text_box}")

        # 按钮
        button = tk.Button(frame, text=btn_labels[i], 
                           font=("Microsoft YaHei", 12), 
                           width=15, 
                           bg=button_bg,
                           command=lambda btn=i: btn_click(btn))
        button.grid(row=i, column=2, padx=5, pady=5)

原因描述:

text_boxes 是一个全局变量,在创建界面的时候,for循环去创建文本框,然后用text_boxes去接收变量,但是!很关键的一个点,首先是在使用时,忘了去对对象进行一个断言,其次是在for循环里面,我是用text_boxes.append,追加到数组里面的,也就是说,如果我多次去重复进入for,那就会从

text_0 一直到 text_n, 但是实际操作又是只有text_0 到 text_4,实际这四个对象在第二次进界面就被覆盖掉了

解决方法:(以下方法任意都可)

  • 在使用对象的地方加个判断,为空不操作

    def btn_click(btn_num):
        if not text_boxes[btn_num].winfo_exists():
            print("obj is unvalid")
            return
    
  • 在for前面对text_boxes数组进行清空

    text_boxes.clear()
    
  • 不使用追加方法

    text_boxes[i] = text_box