如何解决Tkinter结合Python-Requests时的_tkinter.TclError: invalid command name ".!entry"错误
解决Tkinter中
_tkinter.TclError: invalid command name ".!entry"错误 问题根源
- 代码顺序错误:
window.mainloop()是主窗口的事件循环,它执行完毕意味着主窗口已关闭,所有Tkinter组件(包括输入框province)都被销毁,后续调用province.get()自然找不到组件,触发报错。 - 网络请求位置错误:请求接口的代码不该放在主循环之后,必须在窗口存活期间、用户点击按钮时执行,才能获取到输入框的有效内容。
- 多Tk实例问题:在
show函数里新建tk.Tk()是错误的,Tkinter应用只能有一个主Tk对象,次级窗口必须用tk.Toplevel()创建。
修正后的完整代码
import tkinter as tk import requests def fetch_universities(): # 获取输入框的省份名称,去除首尾空格 state_str = province.get().strip() if not state_str: print("请输入省份名称") return # 发送请求获取伊朗大学数据 params = {'country': 'IRAN'} res = requests.get('http://universities.hipolabs.com/search', params=params) if res.status_code == 200: universities = res.json() found = False for uni in universities: # 兼容部分大学state-province字段为空的情况 if uni.get("state-province") == state_str: print(f"大学名称: {uni['name']}") print(f"官网地址: {uni['web_pages'][0]}") found = True if not found: print("未找到该省份的大学") else: print("请求失败,状态码:", res.status_code) def show_result_window(): # 创建次级窗口,使用Toplevel而非Tk top = tk.Toplevel(window) top.title("查询结果") top.geometry('300x100') # 返回按钮,点击销毁次级窗口 return_btn = tk.Button(top, text="返回", width=30, command=top.destroy) return_btn.pack(pady=20) # 主窗口初始化 window = tk.Tk() window.title("伊朗大学查询") window.geometry('400x150') # 创建界面组件 label = tk.Label(window, text="输入省份名称: ", width=15) province = tk.Entry(window, width=30) show_btn = tk.Button(window, text="查询大学", width=20, command=lambda: [fetch_universities(), show_result_window()]) # 布局组件 label.grid(row=0, column=0, padx=10, pady=20) province.grid(row=0, column=1, padx=10, pady=20) show_btn.grid(row=1, column=0, columnspan=2, pady=10) # 启动主事件循环 window.mainloop()
关键修改说明
- 将网络请求逻辑封装到
fetch_universities函数,绑定到查询按钮的点击事件,确保在窗口存活期间获取输入内容。 - 用
tk.Toplevel()替代tk.Tk()创建次级窗口,避免多实例导致的Tcl错误。 - 增加输入为空的校验,以及兼容接口返回数据中
state-province字段为空的情况,提升代码健壮性。 - 使用
command属性绑定按钮事件,替代bind("<Button>", ...),更符合Tkinter常规写法。
内容的提问来源于stack exchange,提问作者Negin
相关产品推荐
相关产品推荐

