Tkinter程序登录后触发SIGSEGV错误(退出码139)的解决方法
Tkinter程序登录后触发SIGSEGV崩溃问题解决
问题现象
- 启动
login_screen()登录界面,使用账号user、密码test登录进入主界面后,点击搜索或描述按钮,程序崩溃并抛出错误:Process finished with exit code 139 (interrupted by signal 11: SIGSEGV) - 直接启动
main_screen()时,所有功能正常运行
问题根源
程序中同时创建了两个独立的Tk()实例(登录窗口和主界面窗口)。Tkinter基于Tcl/Tk实现,不支持多个主应用实例,销毁第一个Tk实例后再创建第二个,会导致底层资源冲突,触发段错误。
修复方案
调整程序结构,只保留一个Tk()主实例,登录窗口使用Toplevel()作为主窗口的子窗口:
from tkinter import * from tkinter import messagebox import json def radio_used(): global x x = radio_state.get() print(x) # Listbox def listbox_used(event): print(listbox.get(listbox.curselection())) def show_list(): global listbox listbox = Listbox(height=5) companies = [] try: with open("data.json", "r") as data_file: data = json.load(data_file) companies = list(data.keys()) except FileNotFoundError: messagebox.showinfo(title="Error", message="未找到数据文件。") return for idx, item in enumerate(companies): listbox.insert(idx, item) listbox.bind("<<ListboxSelect>>", listbox_used) listbox.grid(row=3, column=2) ## 保存数据 def save(): bn = bname_entry.get().strip() nm = name_entry.get().strip() lc = location_entry.get().strip() ph = phone_entry.get().strip() eml = email_entry.get().strip() txt = text.get("1.0", END).strip() if not bn or not ph: messagebox.showinfo(title="Error", message="请确保未留空必填字段(企业名称、手机号)。") return new_data = { bn: { "Name": nm, "Email": eml, "Location": lc, "Phone Number": ph, "Value": x if 'x' in globals() else "", "Description": txt } } try: with open("data.json", "r") as data_file: data = json.load(data_file) data.update(new_data) except FileNotFoundError: data = new_data with open("data.json", "w") as data_file: json.dump(data, data_file, indent=4) # 清空输入框 bname_entry.delete(0, END) phone_entry.delete(0, END) name_entry.delete(0, END) location_entry.delete(0, END) email_entry.delete(0, END) text.delete("1.0", END) # 搜索数据 def find_data(): bn = bname_entry.get().strip() if not bn: messagebox.showinfo(title="Error", message="请输入要搜索的企业名称。") return try: with open("data.json") as data_file: data = json.load(data_file) except FileNotFoundError: messagebox.showinfo(title="Error", message="未找到数据文件。") return if bn in data: info = data[bn] message = (f"姓名: {info['Name']}\n邮箱: {info['Email']}\n" f"手机号: {info['Phone Number']}\n地址: {info['Location']}\n" f"类型: {info['Value']}") messagebox.showinfo(title=bn, message=message) else: messagebox.showwarning(title="提示", message=f"未找到{bn}的相关信息。") # 查看描述 def find_des(): bn = bname_entry.get().strip() if not bn: messagebox.showinfo(title="Error", message="请输入要查询的企业名称。") return try: with open("data.json") as data_file: data = json.load(data_file) except FileNotFoundError: messagebox.showinfo(title="Error", message="未找到数据文件。") return if bn in data: txt = data[bn]["Description"] messagebox.showinfo(title="描述信息", message=txt if txt else "无描述内容") else: messagebox.showwarning(title="提示", message=f"未找到{bn}的描述信息。") # 登录验证 def check_login(): username = u_entry.get().strip() password = p_entry.get().strip() if username == "user" and password == "test": login_window.destroy() window.deiconify() # 显示主窗口 # 登录界面 def login_screen(): global login_window, u_entry, p_entry login_window = Toplevel(window) login_window.title("登录") login_window.config(padx=50, pady=50) login_window.grab_set() # 锁定焦点到登录窗口 login_canvas = Canvas(login_window, height=200, width=200) login_canvas.grid(row=0, column=1) # 标签 u_label = Label(login_window, text="用户名:") u_label.grid(row=1, column=0) p_label = Label(login_window, text="密码:") p_label.grid(row=2, column=0) # 输入框 u_entry = Entry(login_window, width=21) u_entry.grid(row=1, column=1) u_entry.focus() p_entry = Entry(login_window, width=21, show="*") p_entry.grid(row=2, column=1) # 按钮 s_button = Button(login_window, text="登录", width=15, command=check_login) s_button.grid(row=3, column=1) # 主界面 def main_screen(): global window, bname_entry, name_entry, email_entry, location_entry, phone_entry, text, radio_state # 初始化主窗口配置 window.title("数据管理器") window.config(padx=50, pady=50) canvas = Canvas(window, height=200, width=200) canvas.grid(row=0, column=1) # 标签 bname_label = Label(window, text="企业名称:") bname_label.grid(row=1, column=0) name_label = Label(window, text="姓名:") name_label.grid(row=2, column=0) email_label = Label(window, text="邮箱:") email_label.grid(row=3, column=0) location_label = Label(window, text="地址:") location_label.grid(row=4, column=0) phone_label = Label(window, text="手机号:") phone_label.grid(row=5, column=0) # 输入框 bname_entry = Entry(window, width=21) bname_entry.grid(row=1, column=1) bname_entry.focus() name_entry = Entry(window, width=21) name_entry.grid(row=2, column=1) email_entry = Entry(window, width=21) email_entry.grid(row=3, column=1) location_entry = Entry(window, width=21) location_entry.grid(row=4, column=1) phone_entry = Entry(window, width=21) phone_entry.grid(row=5, column=1) # 描述文本框 text = Text(window, height=5, width=30) text.grid(row=6, column=1) text_label = Label(window, text="描述:") text_label.grid(row=6, column=0) # 按钮 search_button = Button(window, text="搜索", width=13, command=find_data) search_button.grid(row=1, column=2) # 单选按钮 radio_state = StringVar() radiobutton1 = Radiobutton(window, text="竞争对手", value="Competitor", variable=radio_state, command=radio_used) radiobutton2 = Radiobutton(window, text="客户", value="Client", variable=radio_state, command=radio_used) radiobutton1.grid(row=7, column=1) radiobutton2.grid(row=8, column=1) company_list_button = Button(window, text="显示企业列表", command=show_list) company_list_button.grid(row=2, column=2) add_button = Button(window, text="添加", width=36, command=save) add_button.grid(row=9, column=1) des_button = Button(window, text="查看描述", width=36, command=find_des) des_button.grid(row=10, column=1) # 程序入口 if __name__ == "__main__": window = Tk() window.withdraw() # 先隐藏主窗口 main_screen() login_screen() window.mainloop()
额外优化点
- 简化登录验证逻辑,移除冗余的
cypher()和user()函数 - 密码输入框添加
show="*"隐藏输入内容 - 增加输入空值检查,提升用户体验
- 优化JSON读写逻辑,减少代码冗余
- 登录窗口添加
grab_set(),确保用户必须完成登录才能操作主窗口
内容的提问来源于stack exchange,提问作者Adam
相关产品推荐
相关产品推荐

