如何在Python程序运行过程中调用Tkinter打开学生信息查询GUI窗口
学生信息查询Tkinter窗口实现方案
核心实现逻辑
- 程序中途弹出窗口用
Toplevel组件实现,无需重复实例化Tk(),避免多窗口冲突 - 可点击学生列表直接用
Listbox组件实现,绑定<<ListboxSelect>>事件即可触发选择回调 - 原有
Student类存在职责混淆问题,先做逻辑拆分,避免课程查询出错
完整可运行代码
1. 修正后的学生管理类
from tkinter import * from tkinter import ttk, messagebox class StudentManager: def __init__(self): # 存储结构:key为学生姓名,value存储学号和课程信息 self.students = {} def add_stu(self, name, n_number): if name not in self.students: self.students[name] = { "n_number": n_number, "courses": {} } def add_course(self, stu_name, cname, score): if stu_name in self.students: self.students[stu_name]["courses"][cname] = score def find_stu_by_nnumber(self, n_number): # 按学号查学生姓名,找不到返回None for name, info in self.students.items(): if info["n_number"] == n_number: return name return None def get_stu_courses(self, stu_name): # 获取指定学生的课程列表,找不到返回空字典 return self.students.get(stu_name, {}).get("courses", {})
2. 查询窗口实现函数
def open_stu_query_window(manager: StudentManager): # 适配非Tkinter程序调用,自动创建隐藏根窗口 root = Tk._default_root if root is None: root = Tk() root.withdraw() # 弹出查询窗口 query_win = Toplevel(root) query_win.title("学生信息查询") query_win.geometry("500x400") # ------------ 学号搜索区域 ------------ search_frame = ttk.Frame(query_win, padding=10) search_frame.pack(fill=X) ttk.Label(search_frame, text="按学号搜索:").pack(side=LEFT, padx=5) search_entry = ttk.Entry(search_frame) search_entry.pack(side=LEFT, padx=5, fill=X, expand=True) search_result_label = ttk.Label(search_frame, text="搜索结果:") search_result_label.pack(side=LEFT, padx=10) def search_stu(event=None): n_num = search_entry.get().strip() if not n_num: search_result_label.config(text="搜索结果:请输入学号") return # 兼容数字/字符串格式学号 try: n_num = int(n_num) except ValueError: pass stu_name = manager.find_stu_by_nnumber(n_num) search_result_label.config(text=f"搜索结果:{stu_name}" if stu_name else "搜索结果:未找到对应学生") # 绑定回车触发搜索 search_entry.bind("<Return>", search_stu) ttk.Button(search_frame, text="搜索", command=search_stu).pack(side=LEFT, padx=5) # ------------ 可点击学生列表区域 ------------ list_frame = ttk.Frame(query_win, padding=10) list_frame.pack(fill=BOTH, expand=True) ttk.Label(list_frame, text="学生列表(点击查看课程):").pack(anchor=W, pady=5) # 创建列表+滚动条 stu_listbox = Listbox(list_frame, width=30, height=10) stu_listbox.pack(side=LEFT, fill=Y, padx=5) scrollbar = ttk.Scrollbar(list_frame, orient=VERTICAL, command=stu_listbox.yview) scrollbar.pack(side=LEFT, fill=Y) stu_listbox.config(yscrollcommand=scrollbar.set) # 插入所有学生姓名 for stu_name in manager.students.keys(): stu_listbox.insert(END, stu_name) # 列表点击回调 def on_select_stu(event=None): selected = stu_listbox.curselection() if not selected: return stu_name = stu_listbox.get(selected[0]) courses = manager.get_stu_courses(stu_name) if not courses: messagebox.showinfo("课程信息", f"学生{stu_name}暂无选修课程") else: course_text = "\n".join([f"{cname}:{score}" for cname, score in courses.items()]) messagebox.showinfo("课程信息", f"学生{stu_name}的选修课程:\n\n{course_text}") # 绑定列表选择事件 stu_listbox.bind("<<ListboxSelect>>", on_select_stu) # ------------ 窗口关闭逻辑 ------------ def on_close(): query_win.destroy() # 销毁自动创建的隐藏根窗口,避免程序卡住 if root is not None and not root.winfo_ismapped(): root.destroy() query_win.protocol("WM_DELETE_WINDOW", on_close) query_win.mainloop()
使用示例
你可以在程序运行的任意位置,初始化完学生数据后直接调用窗口函数即可弹出查询界面:
if __name__ == "__main__": # 模拟你程序运行过程中已经生成的学生数据 stu_manager = StudentManager() # 添加测试学生 stu_manager.add_stu("张三", 2023001) stu_manager.add_stu("李四", 2023002) stu_manager.add_stu("王五", 2023003) # 添加测试课程 stu_manager.add_course("张三", "高等数学", 92) stu_manager.add_course("张三", "大学物理", 85) stu_manager.add_course("李四", "计算机基础", 90) # 程序运行到此处需要打开查询窗口,直接调用即可 open_stu_query_window(stu_manager)
功能说明
- 搜索功能:输入学号后按回车或者点击搜索按钮即可展示对应学生姓名,学号不存在会给出提示
- 可点击列表:点击列表中的任意学生姓名,会自动弹窗展示该学生的所有选修课程和分数,无选课也会给出对应提示
- 兼容非Tkinter主程序:如果你的主程序不是用Tkinter开发的,调用时也会自动处理主循环逻辑,不会出现窗口无响应问题
内容的提问来源于stack exchange,提问作者M2.
相关产品推荐
相关产品推荐

