行业资讯

Python Tkinter 普通类封装:从零开始构建你的第一个 GUI 应用

发布时间:2026/8/6 4:56:23
Python Tkinter 普通类封装:从零开始构建你的第一个 GUI 应用 本文适合谁已经了解 Python 基础语法函数、变量、列表等对类class有初步认识但还不太熟练想用 Tkinter 做 GUI 程序但不想一上来就接触复杂的继承想理解面向对象在实际项目中到底怎么用 第一部分Tkinter 基础入门1.1 什么是 TkinterTkinter 是 Python 自带的标准 GUI图形用户界面库。它的名字来源于 Tk interface不需要额外安装只要安装了 Python 就可以直接使用。import tkinter as tk # 导入模块起个别名 tk1.2 创建第一个窗口import tkinter as tk # 创建窗口 window tk.Tk() window.title(我的第一个窗口) window.geometry(400x300) # 启动窗口必须最后写 window.mainloop()核心要点tk.Tk()创建一个空白窗口是所有组件的根容器mainloop()让窗口保持显示监听用户操作必须作为最后一行代码 第二部分Tkinter 核心组件详解2.1 窗口Tk——所有组件的大本营Tk是 Tkinter 的根窗口所有其他组件都必须放在它上面。常用方法方法说明示例title()设置窗口标题window.title(我的应用)geometry()设置窗口大小和位置window.geometry(400x300)resizable()是否允许用户拉伸窗口window.resizable(False, False)iconbitmap()设置窗口图标window.iconbitmap(icon.ico)destroy()关闭窗口window.destroy()import tkinter as tk window tk.Tk() window.title(窗口示例) # 设置标题 window.geometry(400x30010050) # 宽400高300位于屏幕(100,50) window.resizable(False, False) # 不允许拉伸 window.mainloop()2.2 标签Label——显示文字或图片Label 用于显示文本或图像用户不能直接编辑它的内容。常用参数参数说明示例text显示的文本text你好font字体和大小font(微软雅黑, 16)fg/bg前景色/背景色fgred/bgyellowwidth/height宽度/高度字符数width20import tkinter as tk window tk.Tk() label1 tk.Label(window, text普通标签) label1.pack() label2 tk.Label(window, text红色大字体, fgred, font(微软雅黑, 20)) label2.pack() label3 tk.Label(window, text黄色背景, bgyellow, width20, height2) label3.pack() window.mainloop()2.3 按钮Button——触发操作的入口Button 用于响应用户点击执行指定的函数。常用参数参数说明示例text按钮上显示的文字text点击我command点击时执行的函数commandmy_functionfg/bg文字颜色/背景色fgwhite/bgbluestate按钮状态statedisabled禁用重要command绑定时不加括号import tkinter as tk def say_hello(): print(你好) window tk.Tk() # ✅ 正确不加括号传递函数本身 tk.Button(window, text打招呼, commandsay_hello).pack() # ❌ 错误加了括号会在创建时立即执行 # tk.Button(window, text打招呼, commandsay_hello()).pack() # 带参数的情况使用 lambda tk.Button(window, text打招呼, commandlambda: print(带参数的你好)).pack() window.mainloop()2.4 输入框Entry——接收单行文本Entry 用于让用户输入单行文本。常用方法方法说明示例get()获取输入框内容text entry.get()insert()在指定位置插入文字entry.insert(0, 默认文字)delete()删除指定范围的文字entry.delete(0, tk.END)import tkinter as tk window tk.Tk() # 创建输入框 entry tk.Entry(window, width30) entry.pack() # 插入默认文字0 表示从头开始 entry.insert(0, 请输入内容) # 按钮获取输入内容 def show_text(): content entry.get() print(输入内容, content) tk.Button(window, text显示内容, commandshow_text).pack() # 按钮清空输入框 def clear_text(): entry.delete(0, tk.END) tk.Button(window, text清空, commandclear_text).pack() # 密码输入框显示为星号 password_entry tk.Entry(window, show*) password_entry.pack() window.mainloop()2.5 多行文本框Text——接收多行文本Text 用于让用户输入多行文本。常用方法方法说明示例get()获取内容需指定范围text.get(1.0, tk.END)insert()插入文字text.insert(tk.END, 新内容)delete()删除内容text.delete(1.0, tk.END)注意1.0表示第 1 行第 0 列即开头import tkinter as tk window tk.Tk() # 创建多行文本框 text_area tk.Text(window, width40, height10) text_area.pack() # 插入默认文字 text_area.insert(tk.END, 这是多行文本框\n你可以输入多行文字) # 获取所有内容 def get_all_text(): content text_area.get(1.0, tk.END) print(所有内容, content) tk.Button(window, text获取内容, commandget_all_text).pack() window.mainloop()2.6 列表框Listbox——显示选项列表Listbox 用于展示一个选项列表用户可以从中选择。常用方法方法说明示例insert()插入选项listbox.insert(tk.END, 选项1)delete()删除选项listbox.delete(0)删除第一个curselection()获取选中的索引index listbox.curselection()get()获取指定位置的文字item listbox.get(0)import tkinter as tk window tk.Tk() listbox tk.Listbox(window, width30, height5) listbox.pack() # 添加选项 items [苹果, 香蕉, 橙子, 西瓜, 葡萄] for item in items: listbox.insert(tk.END, item) # 获取选中的选项 def show_selected(): selection listbox.curselection() if selection: index selection[0] print(你选择了, listbox.get(index)) else: print(没有选中任何项目) tk.Button(window, text显示选中, commandshow_selected).pack() window.mainloop()2.7 框架Frame——组件容器Frame 是一个容器用于分组和布局其他组件本身不显示任何内容。import tkinter as tk window tk.Tk() # 创建两个框架不同背景色便于区分 frame1 tk.Frame(window, bglightblue, width200, height100) frame1.pack(sidetk.LEFT, padx10) frame2 tk.Frame(window, bglightgreen, width200, height100) frame2.pack(sidetk.LEFT, padx10) # 在 frame1 中添加组件 tk.Label(frame1, text左框架, bglightblue).pack() tk.Button(frame1, text按钮1).pack() # 在 frame2 中添加组件 tk.Label(frame2, text右框架, bglightgreen).pack() tk.Button(frame2, text按钮2).pack() window.geometry(450x150) window.mainloop() 第三部分三大布局管理器Tkinter 提供了三种布局方式每个组件只能用其中一种不能混用。3.1 pack() —— 自动排队pack()是最简单的布局方式组件按添加顺序自动排列。常用参数参数说明示例side排列方向sidetk.LEFT/tk.RIGHT/tk.TOP/tk.BOTTOMfill填充方向filltk.X水平填充 /tk.Y垂直填充padx/pady外边距padx10/pady5expand是否扩展expandTrue占满剩余空间import tkinter as tk window tk.Tk() window.geometry(300x200) # 默认从上到下 tk.Button(window, text上).pack() tk.Button(window, text中).pack() tk.Button(window, text下).pack() # 从左到右排列 tk.Button(window, text左).pack(sidetk.LEFT) tk.Button(window, text中).pack(sidetk.LEFT) tk.Button(window, text右).pack(sidetk.LEFT) window.mainloop()3.2 grid() —— 表格排列grid()像 Excel 表格一样通过行和列来精确定位组件。常用参数参数说明示例row行号从 0 开始row0column列号从 0 开始column1rowspan跨行数rowspan2columnspan跨列数columnspan3padx/pady外边距padx5/pady5sticky对齐方向stickyw左对齐/e右对齐import tkinter as tk window tk.Tk() window.title(登录界面) # 第0行用户名 tk.Label(window, text用户名).grid(row0, column0, padx5, pady5) tk.Entry(window).grid(row0, column1, padx5, pady5) # 第1行密码 tk.Label(window, text密码).grid(row1, column0, padx5, pady5) tk.Entry(window, show*).grid(row1, column1, padx5, pady5) # 第2行登录按钮跨两列居中 tk.Button(window, text登录).grid(row2, column0, columnspan2, pady10) window.mainloop()3.3 place() —— 精确定位place()使用 X、Y 坐标精确定位组件像素级别。常用参数参数说明示例x水平位置像素x50y垂直位置像素y100width/height组件宽高width100/height50import tkinter as tk window tk.Tk() window.geometry(400x300) # 精确放置在坐标 (50, 100) tk.Button(window, text我在(50,100)).place(x50, y100) # 精确放置在坐标 (200, 50) tk.Button(window, text我在(200,50)).place(x200, y50) # 精确放置在右下角结合窗口大小 tk.Button(window, text右下角).place(x300, y250) window.mainloop()⚠️ 注意事项place()不会自适应窗口大小变化通常用于简单布局或特殊需求复杂应用建议优先使用pack()或grid() 第四部分常用功能方法4.1 修改组件属性configureimport tkinter as tk def change(): # 动态修改标签的文字和颜色 label.config(text文字已修改, fgred, bgyellow) window tk.Tk() label tk.Label(window, text初始文字) label.pack() tk.Button(window, text修改, commandchange).pack() window.mainloop()4.2 消息框messageboxfrom tkinter import messagebox def show_messages(): messagebox.showinfo(提示, 这是一个提示信息) messagebox.showwarning(警告, 这是一个警告) messagebox.showerror(错误, 这是一个错误) # 确认对话框返回 True/False result messagebox.askyesno(确认, 你确定吗) print(用户选择, result) window tk.Tk() tk.Button(window, text弹出各种框, commandshow_messages).pack() window.mainloop()4.3 文件对话框filedialogfrom tkinter import filedialog def choose_file(): # 选择文件 file_path filedialog.askopenfilename(title选择文件) print(选择的文件, file_path) # 选择文件夹 folder_path filedialog.askdirectory(title选择文件夹) print(选择的文件夹, folder_path) # 保存文件 save_path filedialog.asksaveasfilename(title保存文件) print(保存路径, save_path) window tk.Tk() tk.Button(window, text选择文件, commandchoose_file).pack() window.mainloop() 第五部分用普通类封装掌握了上面的基础组件和方法后我们来看看如何用类来组织代码。5.1 第一步从脚本式代码开始import tkinter as tk window tk.Tk() window.title(计数器) count 0 def add(): global count count 1 label.config(textf点击了 {count} 次) label tk.Label(window, text点击了 0 次) label.pack() button tk.Button(window, text点我1, commandadd) button.pack() window.mainloop()5.2 第二步升级为普通类封装import tkinter as tk class CounterApp: 一个简单的计数器应用 def __init__(self): # 创建窗口 self.window tk.Tk() self.window.title(计数器) self.window.geometry(300x150) # 创建变量现在是对象的属性 self.count 0 # 创建组件现在是对象的属性 self.label tk.Label(self.window, text点击了 0 次) self.label.pack(pady20) self.button tk.Button(self.window, text点我1, commandself.add) self.button.pack() def add(self): 点击按钮时执行的方法 self.count 1 self.label.config(textf点击了 {self.count} 次) def run(self): 启动应用 self.window.mainloop() # 使用 if __name__ __main__: app CounterApp() app.run()5.3 核心变化对比对比项脚本式写法类封装写法窗口变量window全局self.window对象属性计数变量count全局self.count对象属性功能函数def add()独立函数def add(self)类方法启动方式window.mainloop()app.run()核心原则所有变量加self.变成对象的属性所有函数加self参数变成类的方法添加一个run()方法来启动程序 第六部分实战案例——学生信息管理系统综合运用上面学到的所有知识我们来做一个完整的学生信息管理系统。6.1 需求分析功能包括输入学生姓名和年龄点击添加按钮将信息显示在列表中点击删除选中删除选中的学生点击清空清空所有信息import tkinter as tk from tkinter import messagebox class StudentManager: 学生信息管理系统 def __init__(self): # 创建窗口 self.window tk.Tk() self.window.title(学生信息管理系统) self.window.geometry(400x350) self.window.resizable(False, False) # 存储学生数据 self.students [] # 创建界面 self.create_widgets() def create_widgets(self): 创建所有界面组件 # ---- 输入区域 ---- input_frame tk.Frame(self.window) input_frame.pack(pady10) # 姓名 tk.Label(input_frame, text姓名).grid(row0, column0, padx5) self.entry_name tk.Entry(input_frame, width15) self.entry_name.grid(row0, column1, padx5) # 年龄 tk.Label(input_frame, text年龄).grid(row0, column2, padx5) self.entry_age tk.Entry(input_frame, width10) self.entry_age.grid(row0, column3, padx5) # 添加按钮 tk.Button(input_frame, text添加, commandself.add_student).grid(row0, column4, padx10) # 支持回车键快速添加 self.entry_age.bind(Return, lambda event: self.add_student()) # ---- 显示区域 ---- self.listbox tk.Listbox(self.window, width50, height10) self.listbox.pack(pady10) # ---- 操作按钮 ---- button_frame tk.Frame(self.window) button_frame.pack() tk.Button(button_frame, text删除选中, commandself.delete_selected, width10).pack(sidetk.LEFT, padx5) tk.Button(button_frame, text清空全部, commandself.clear_all, width10).pack(sidetk.LEFT, padx5) tk.Button(button_frame, text退出程序, commandself.quit_app, width10).pack(sidetk.LEFT, padx5) # 显示当前人数 self.count_label tk.Label(self.window, text当前总人数0) self.count_label.pack(pady5) def update_count(self): 更新人数显示 self.count_label.config(textf当前总人数{len(self.students)}) def add_student(self): 添加学生信息 name self.entry_name.get().strip() age self.entry_age.get().strip() # 数据校验 if not name: messagebox.showwarning(警告, 请输入学生姓名) self.entry_name.focus() return if not age: messagebox.showwarning(警告, 请输入学生年龄) self.entry_age.focus() return if not age.isdigit(): messagebox.showwarning(警告, 年龄必须是数字) self.entry_age.delete(0, tk.END) self.entry_age.focus() return # 检查年龄范围 age_int int(age) if age_int 0 or age_int 150: messagebox.showwarning(警告, 年龄必须在 0-150 之间) self.entry_age.delete(0, tk.END) self.entry_age.focus() return # 添加数据 student_info f{name}{age_int}岁 self.students.append(student_info) self.listbox.insert(tk.END, student_info) # 清空输入框 self.entry_name.delete(0, tk.END) self.entry_age.delete(0, tk.END) self.entry_name.focus() # 更新人数 self.update_count() messagebox.showinfo(成功, f已成功添加{student_info}) def delete_selected(self): 删除选中的学生 selection self.listbox.curselection() if not selection: messagebox.showwarning(警告, 请先在列表中选中要删除的学生) return index selection[0] student_name self.students[index] # 二次确认 if messagebox.askyesno(确认, f确定要删除「{student_name}」吗): self.listbox.delete(index) del self.students[index] self.update_count() messagebox.showinfo(成功, 已成功删除该学生信息) def clear_all(self): 清空所有数据 if not self.students: messagebox.showinfo(提示, 列表已经是空的无需清空) return if messagebox.askyesno(确认, 确定要清空所有学生数据吗\n此操作不可撤销): self.listbox.delete(0, tk.END) self.students.clear() self.update_count() messagebox.showinfo(成功, 已清空所有学生数据) def quit_app(self): 退出程序 if messagebox.askyesno(确认, 确定要退出程序吗): self.window.destroy() def run(self): 启动应用 self.window.mainloop() # 启动程序 if __name__ __main__: app StudentManager() app.run()6.3 代码亮点解析数据封装self.students列表只属于这个应用不会和外部冲突界面分离create_widgets专门负责界面布局__init__保持简洁方法组织每个功能都是一个独立的方法职责清晰用户体验支持回车键提交、自动聚焦、二次确认等细节数据校验对姓名、年龄做了完整的校验处理 第七部分常见问题解答Q1为什么要写run()方法不能直接调用mainloop()吗当然可以你可以直接写app.window.mainloop()。但为了封装性我们通常提供一个run()方法让调用者不需要关心内部实现细节只调用app.run()即可。Q2普通类封装和继承式封装应该选哪个场景推荐方式刚开始学习想理解类的作用普通类封装 ✅只需要一个主窗口两种都可以需要管理多个窗口普通类封装 ✅类还需要继承其他非 Tkinter 类普通类封装 ✅想写最简洁的 Tkinter 代码继承式封装 ✅Q3什么时候用pack()什么时候用grid()pack()适合简单的上下左右排列组件数量少grid()适合复杂的表格排列组件数量多且有规律place()适合精确定位或自定义布局记住一个容器内的所有组件只能使用同一种布局方式 第八部分知识点速查表8.1 常用组件速查组件用途常用方法Tk根窗口title(),geometry(),mainloop()Label显示文字/图片config()Button触发操作config()Entry单行输入get(),insert(),delete()Text多行输入get(),insert(),delete()Listbox显示选项列表insert(),delete(),curselection()Frame容器分组pack(),grid()8.2 三大布局对比特点pack()grid()place()易用性⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐精确度⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐自适应⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐适合场景简单顺序排列表格状排列精确定位8.3 从普通代码升级到类的步骤# 第1步创建类 class MyApp: def __init__(self): # 第2步window 变成 self.window self.window tk.Tk() # 第3步所有变量改成 self.变量名 self.count 0 self.label tk.Label(self.window, ...) # 第4步函数调用改成 self.方法名 self.button tk.Button(..., commandself.add) # 第5步函数变成类的方法 def add(self): self.count 1 # 第6步添加启动方法 def run(self): self.window.mainloop() 结语通过本文的学习你应该已经掌握了✅ Tkinter 的所有核心组件Label、Button、Entry、Text、Listbox、Frame✅ 三大布局管理器pack、grid、place的用法和区别✅ 常用的功能方法configure、messagebox、filedialog✅ 为什么要用类来封装 Tkinter 代码✅ 如何将普通代码升级为类封装✅ 完成了一个完整的学生信息管理系统如果你觉得这篇文章有帮助欢迎点赞、收藏、分享有任何问题也可以在评论区留言交流。