import tkinter as tkfrom tkinterimport messagebox, Toplevel# 解析文本构建三级树形字典 + 三级专业检索列表major_tree = {}search_all_l3 = []lines = [line.strip() for line in txt_zhuanye.splitlines() if line.strip()]for line in lines: code, name = line.split(" ", 1) if len(code) == 2: major_tree[code] = { "name": name, "children": {} } elif len(code) == 4: parent_code = code[:2] major_tree[parent_code]["children"][code] = { "name": name, "children": {} } elif len(code) >= 6: l1_code = code[:2] l2_code = code[:4] major_tree[l1_code]["children"][l2_code]["children"][code] = name search_all_l3.append({ "l1": l1_code, "l2": l2_code, "l3_code": code, "l3_name": name, "full_text": f"{code}{name}" })class MajorSelectWindow: def __init__(self, root_win): self.root = root_win self.root.title("高考志愿专业选择工具——阳光教育祝你金榜题名!!!") self.root.geometry("960x580") self.root.resizable(True, True) self.root.configure(bg="#fff8ee") # 全局状态 self.active_panel_index = 0 self.select_l1 = None self.select_l2 = None self.select_l3 = None # 1. 顶部搜索栏 search_frame = tk.Frame(self.root, bg="#ff7838", padx=12, pady=10) search_frame.pack(fill=tk.X) tk.Label( search_frame, text="专业搜索:", font=("微软雅黑", 12, "bold"), fg="white", bg="#ff7838" ).pack(side=tk.LEFT, padx=5) self.search_entry = tk.Entry( search_frame, font=("微软雅黑", 11), width=45, bg="#fffdf0", fg="#222222" ) self.search_entry.pack(side=tk.LEFT, padx=8) self.search_entry.bind("<Return>", self.do_search) self.search_btn = tk.Button( search_frame, text="🔍 搜索专业", font=("微软雅黑", 11, "bold"), bg="#ff3d3d", fg="white", activebackground="#ff6666", command=self.do_search ) self.search_btn.pack(side=tk.LEFT, padx=10) self.clear_btn = tk.Button( search_frame, text="重置全部", font=("微软雅黑", 10), bg="#3388ff", fg="white", activebackground="#66aaff", command=self.load_level1 ) self.clear_btn.pack(side=tk.LEFT, padx=5) # 2. 主三栏容器 main_container = tk.Frame(self.root, bg="#fff8ee", padx=12, pady=8) main_container.pack(fill=tk.BOTH, expand=True) frame_l1 = tk.LabelFrame( main_container, text="🔴 一级学科门类", font=("微软雅黑", 11, "bold"), fg="#d82626", bg="#fff8ee", padx=6, pady=6 ) frame_l2 = tk.LabelFrame( main_container, text="🟡 二级专业类", font=("微软雅黑", 11, "bold"), fg="#d89000", bg="#fff8ee", padx=6, pady=6 ) frame_l3 = tk.LabelFrame( main_container, text="🔵 三级具体专业", font=("微软雅黑", 11, "bold"), fg="#0058d8", bg="#fff8ee", padx=6, pady=6 ) frame_l1.grid(row=0, column=0, sticky="nsew", padx=6) frame_l2.grid(row=0, column=1, sticky="nsew", padx=6) frame_l3.grid(row=0, column=2, sticky="nsew", padx=6) main_container.columnconfigure(0, weight=1) main_container.columnconfigure(1, weight=1) main_container.columnconfigure(2, weight=10) main_container.rowconfigure(0, weight=1) # 列表框 self.list_l1 = tk.Listbox( frame_l1, font=("Microsoft YaHei", 11), exportselection=False, bg="#fff2f2", fg="#880000" ) self.list_l2 = tk.Listbox( frame_l2, font=("Microsoft YaHei", 11), exportselection=False, bg="#fffbf0", fg="#704000" ) self.list_l3 = tk.Listbox( frame_l3, font=("Microsoft YaHei", 11), exportselection=False, bg="#f0f7ff", fg="#002870" ) self.list_l1.pack(fill=tk.BOTH, expand=True) self.list_l2.pack(fill=tk.BOTH, expand=True) self.list_l3.pack(fill=tk.BOTH, expand=True) # 绑定事件 self.list_l1.bind("<<ListboxSelect>>", self.on_click_l1) self.list_l2.bind("<<ListboxSelect>>", self.on_click_l2) self.list_l3.bind("<<ListboxSelect>>", self.on_click_l3) self.root.bind("<Left>", self.key_switch_left) self.root.bind("<Right>", self.key_switch_right) self.root.bind("<Up>", self.key_up_item) self.root.bind("<Down>", self.key_down_item) self.root.bind("<Return>", self.key_confirm) self.load_level1() self.refresh_active_highlight() # 搜索逻辑 def do_search(self, event=None): keyword = self.search_entry.get().strip() if not keyword: messagebox.showwarning("提示", "请输入要搜索的专业名称!") return result_list = [] for item in search_all_l3: if keyword in item["full_text"]: result_list.append(item) if len(result_list) == 0: messagebox.showinfo("搜索结果", f"未找到包含「{keyword}」的三级专业") return elif len(result_list) == 1: self.jump_to_major(result_list[0]) else: self.show_multi_select_window(result_list) def show_multi_select_window(self, res_list): top = Toplevel(self.root) top.title("多条匹配结果,请选择") top.geometry("520x320") top.configure(bg="#fff8ee") tk.Label(top, text="匹配到多条专业,双击选择:", font=("微软雅黑",11,"bold"), bg="#fff8ee").pack(pady=8) lb = tk.Listbox(top, font=("微软雅黑",10), bg="#f0f7ff") lb.pack(fill=tk.BOTH, expand=True, padx=10, pady=5) for item in res_list: lb.insert(tk.END, item["full_text"]) def double_click(evt): sel = lb.curselection() if sel: self.jump_to_major(res_list[sel[0]]) top.destroy() lb.bind("<Double-Button-1>", double_click) def jump_to_major(self, l3_info): l1_code = l3_info["l1"] l2_code = l3_info["l2"] l3_full = l3_info["full_text"] self.load_level1() self.select_l1 = l1_code for i in range(self.list_l1.size()): if self.list_l1.get(i).startswith(l1_code): self.list_l1.selection_set(i) self.list_l1.see(i) break self.load_level2(l1_code) self.select_l2 = l2_code for i in range(self.list_l2.size()): if self.list_l2.get(i).startswith(l2_code): self.list_l2.selection_set(i) self.list_l2.see(i) break self.load_level3(l1_code, l2_code) self.select_l3 = l3_full for i in range(self.list_l3.size()): if self.list_l3.get(i) == l3_full: self.list_l3.selection_set(i) self.list_l3.see(i) break self.active_panel_index = 2 self.refresh_active_highlight() self.update_status_tip() # 数据加载 def load_level1(self): self.search_entry.delete(0, tk.END) self.list_l1.delete(0, tk.END) self.list_l2.delete(0, tk.END) self.list_l3.delete(0, tk.END) self.select_l1 = self.select_l2 = self.select_l3 = None for code in sorted(major_tree.keys()): self.list_l1.insert(tk.END, f"{code}{major_tree[code]['name']}") self.active_panel_index = 0 self.refresh_active_highlight() self.update_status_tip() def load_level2(self, l1_code): self.list_l2.delete(0, tk.END) self.list_l3.delete(0, tk.END) self.select_l2 = self.select_l3 = None l1_data = major_tree[l1_code] for code in sorted(l1_data["children"].keys()): self.list_l2.insert(tk.END, f"{code}{l1_data['children'][code]['name']}") self.update_status_tip() def load_level3(self, l1_code, l2_code): self.list_l3.delete(0, tk.END) self.select_l3 = None l2_data = major_tree[l1_code]["children"][l2_code] for code in sorted(l2_data["children"].keys()): self.list_l3.insert(tk.END, f"{code}{l2_data['children'][code]}") self.update_status_tip() # 鼠标点击 def on_click_l1(self, event): sel = self.list_l1.curselection() if not sel: return l1_code = self.list_l1.get(sel[0]).split(" ")[0] self.select_l1 = l1_code self.load_level2(l1_code) def on_click_l2(self, event): if not self.select_l1: return sel = self.list_l2.curselection() if not sel: return l2_code = self.list_l2.get(sel[0]).split(" ")[0] self.select_l2 = l2_code self.load_level3(self.select_l1, l2_code) def on_click_l3(self, event): sel = self.list_l3.curselection() if sel: self.select_l3 = self.list_l3.get(sel[0]) self.update_status_tip() # 激活高亮 def refresh_active_highlight(self): self.list_l1.config(bg="#fff2f2") self.list_l2.config(bg="#fffbf0") self.list_l3.config(bg="#f0f7ff") if self.active_panel_index == 0: self.list_l1.config(bg="#ffdede") elif self.active_panel_index == 1: self.list_l2.config(bg="#fff3c9") else: self.list_l3.config(bg="#d6e7ff") # 状态栏更新 def update_status_tip(self): msg = [] if self.select_l1: msg.append(f"一级:{self.select_l1}{major_tree[self.select_l1]['name']}") if self.select_l2: l2name = major_tree[self.select_l1]["children"][self.select_l2]["name"] msg.append(f"二级:{self.select_l2}{l2name}") if self.select_l3: msg.append(f"三级:{self.select_l3}")if __name__ == "__main__": window = tk.Tk() app = MajorSelectWindow(window) window.mainloop()