Mac平台使用Tkinter触发'interrupted by signal 11: SIGSEGV'错误求助
问题描述
登录成功进入任务管理器后,点击“添加任务”“查看我的任务”“查看全部任务”“删除任务”“清空全部”“退出登录”任一选项时,十次中有九次会出现interrupted by signal 11: SIGSEGV错误,该如何排查原因?
相关代码
import tkinter as tk from tkinter import messagebox class LoginWindow: def __init__(self, master): self.master = master # 父窗口 self.master.title("登录界面") self.master.geometry('800x500') # 设置背景色 self.master.configure(bg="turquoise") # 创建用户名标签和输入框 self.username_label = tk.Label(self.master, text="用户名:", bg="turquoise", font=('Arial', 19)) self.username_label.pack(padx=10, pady=5) self.username_entry = tk.Entry(self.master) self.username_entry.pack(padx=10, pady=5) # 创建密码标签和输入框 self.password_label = tk.Label(self.master, text="密码:", bg="turquoise", font=('Arial', 19)) self.password_label.pack(padx=10, pady=5) self.password_entry = tk.Entry(self.master, show="*") self.password_entry.pack(padx=10, pady=5) # 创建登录按钮 self.login_button = tk.Button(self.master, text="登录", command=self.login, font=('Arial', 19, 'bold')) self.login_button.pack(padx=10, pady=25) # 存储用户名和密码的字典 self.users = { "admin": "password", "user1": "pass1", "user2": "pass2" } def login(self): username = self.username_entry.get() # 获取用户输入 password = self.password_entry.get() # 验证用户名密码 if username in self.users and self.users[username] == password: self.master.destroy() # 关闭登录窗口 TaskManagerWindow(username) # 打开任务管理器窗口 else: messagebox.showerror("登录失败", "用户名或密码错误,请重试。") class TaskManagerWindow: def __init__(self, username): self.username = username self.master = tk.Tk() # 根窗口 self.master.title("任务管理器") # 设置背景色 self.master.configure(bg="light green") # 创建任务列表 self.task_list = tk.Listbox(self.master, width=50) self.task_list.grid(row=0, column=0, padx=10, pady=10, columnspan=6, rowspan=4) # 创建任务输入框 self.task_entry = tk.Entry(self.master) self.task_entry.grid(row=5, column=0, padx=30, pady=5) self.task_entry.insert(tk.END, "Task...") self.task_entry.bind("<FocusIn>", self.clear_entry) # 创建归属用户输入框 self.username_entry = tk.Entry(self.master) self.username_entry.grid(row=5, column=1, padx=0, pady=5) self.username_entry.insert(tk.END, "Attributed to...") self.username_entry.bind("<FocusIn>", self.clear_username_entry) # 创建添加按钮 self.add_button = tk.Button(self.master, text="添加任务", command=self.add_task, fg="orchid4") self.add_button.grid(row=0, column=7, padx=5, sticky="se") # 创建查看我的任务按钮 self.view_mine_button = tk.Button(self.master, text="查看我的任务", command=self.view_mine, fg="DeepSkyBlue2") self.view_mine_button.grid(row=1, column=7, padx=5, sticky="e") # 创建查看全部任务按钮 self.view_all_button = tk.Button(self.master, text="查看全部任务", command=self.view_all, fg="DeepSkyBlue2") self.view_all_button.grid(row=1, column=8, padx=5, sticky="w") # 创建删除任务按钮 self.delete_button = tk.Button(self.master, text="删除任务", command=self.delete_task, fg="red4") self.delete_button.grid(row=2, column=7, padx=5, sticky="ne") # 创建清空全部按钮 self.clear_button = tk.Button(self.master, text="清空全部", command=self.clear_tasks, fg="red4") self.clear_button.grid(row=2, column=8, padx=5, pady=5, sticky="nw") # 创建退出登录按钮 self.logout_button = tk.Button(self.master, text="退出登录", command=self.logout) self.logout_button.grid(row=5, column=8, padx=5, pady=5, sticky="w") # 存储任务的列表 self.tasks = [] def add_task(self): task = self.task_entry.get() username = self.username_entry.get() if task and task != "type..." and username and username != "username...": self.tasks.append({"task": task, "user": username}) self.task_list.insert(tk.END, task) self.task_entry.delete(0, tk.END) self.task_entry.insert(tk.END, "Task...") self.username_entry.delete(0, tk.END) self.username_entry.insert(tk.END, "Attributed to...") else: messagebox.showwarning("任务管理器", "请输入任务和归属用户。") def delete_task(self): selected_indices = self.task_list.curselection() if selected_indices: # 倒序遍历选中索引,避免删除时索引偏移 for index in reversed(selected_indices): self.task_list.delete(index) del self.tasks[index] else: messagebox.showwarning("任务管理器", "请选择要删除的任务。") def clear_tasks(self): confirmed = messagebox.askyesno("任务管理器", "确定要清空所有任务吗?") if confirmed: self.task_list.delete(0, tk.END) self.tasks = [] def clear_entry(self, event): current_value = self.task_entry.get() if current_value == "Task...": self.task_entry.delete(0, tk.END) def clear_username_entry(self, event): current_value = self.username_entry.get() if current_value == "Attributed to...": self.username_entry.delete(0, tk.END) def view_mine(self): self.task_list.delete(0, tk.END) for task in self.tasks: if task['user'] == self.username: self.task_list.insert(tk.END, task['task']) def view_all(self): self.task_list.delete(0, tk.END) for task in self.tasks: self.task_list.insert(tk.END, task['task']) def logout(self): confirmed = messagebox.askyesno("任务管理器", "确定要退出登录吗?") if confirmed: self.master.destroy() # 关闭任务管理器窗口 root = tk.Tk() LoginWindow(root) root.mainloop() def run(self): self.master.mainloop() def main(): root = tk.Tk() LoginWindow(root) root.mainloop() if __name__ == "__main__": main()
排查与修复方案
修复多窗口创建逻辑(核心问题):tkinter不允许同时存在多个
tk.Tk()实例,这会导致内部GUI资源冲突,大概率是触发段错误的原因。原代码登录时销毁主窗口、任务管理器新建Tk(),退出登录又重复创建Tk(),完全违背tkinter的窗口管理规范。
修正方式:- 登录时隐藏原窗口而非销毁,用
Toplevel()创建任务管理器子窗口 - 退出登录时销毁子窗口,重新显示原登录窗口
关键代码修改:
# LoginWindow的login方法 def login(self): username = self.username_entry.get() password = self.password_entry.get() if username in self.users and self.users[username] == password: self.master.withdraw() # 隐藏登录窗口 app = TaskManagerWindow(self.master, username) # 传递原父窗口 app.run() # TaskManagerWindow的初始化方法 def __init__(self, parent, username): self.parent = parent self.username = username self.master = tk.Toplevel(parent) # 创建子窗口 self.master.title("任务管理器") # 其余代码不变 # TaskManagerWindow的logout方法 def logout(self): confirmed = messagebox.askyesno("任务管理器", "确定要退出登录吗?") if confirmed: self.master.destroy() self.parent.deiconify() # 重新显示登录窗口- 登录时隐藏原窗口而非销毁,用
修正条件判断不一致问题:
add_task方法里判断task != "type...",但输入框默认提示是"Task...",这会导致正常输入的任务被误拦截,虽然不直接引发段错误,但可能触发异常间接影响程序稳定性,改成task != "Task..."即可。用调试工具定位底层问题:如果修复后仍有段错误,在Linux/macOS下可以用
gdb调试:gdb python (gdb) run your_script.py # 触发错误后输入bt查看调用栈 (gdb) btWindows下可以用Visual Studio附加到Python进程,捕获段错误的调用栈,确定是tkinter哪个底层函数出问题。
升级Python和tkinter版本:老旧版本的tkinter存在已知的段错误bug,升级到Python 3.10及以上的稳定版,能解决不少底层兼容性问题。
内容的提问来源于stack exchange,提问作者user22231632
相关产品推荐
相关产品推荐

