# tkinter **Repository Path**: xuyan-breeze/tkinter ## Basic Information - **Project Name**: tkinter - **Description**: python tkinter库的学习记录 - **Primary Language**: Python - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 3 - **Forks**: 0 - **Created**: 2025-08-29 - **Last Updated**: 2026-01-03 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # **tkinter库 - 基础总结** **作者:XuYan** **时间:2025-07-04** [TOC] ## 1 主程序 ~~~python import tkinter as tk from tkinter import ttk # 主题化小部件 from tkinter import messagebox # 消息弹窗 def main(): """ 主程序函数 负责程序的整体流程控制 """ # 第1步:创建并设置窗口 root = setup_window() # 第2步:创建Label标签 create_label(root) # 第3步:创建按钮 creat_button(root) # 第4步:启动主循环,让窗口显示出来 root.mainloop() # 当这个文件被直接运行时,执行main()函数 if __name__ == "__main__": main() ~~~ ## 2 创建并设置窗口 ### 2.1 创建主窗口 ```python import tkinter as tk def setup_window(): """ 设置主窗口的函数 返回:配置好的主窗口对象 """ # 创建主窗口对象 root = tk.Tk() ``` - 导入tkinter模块,并给它一个简短的别名`tk` - tkinter是Python**内置的GUI库**,不需要单独安装 - 创建主窗口对象 `root`变量 ### 2.2 设置窗口属性 ```python import tkinter as tk def setup_window(): """ 设置主窗口的函数 返回:配置好的主窗口对象 """ # 创建主窗口对象 root = tk.Tk() # 1. 设置窗口标题 root.title("我的第一个tkinter窗口") # 2. 设置窗口大小(宽x高) root.geometry("600x400") # 3. 设置窗口在屏幕中央显示 root.geometry("600x400+500+200") # 4. 设置窗口背景颜色 root.configure(bg="lightblue") # 5. 是否拖拽边框改变大小(宽度, 高度) root.resizable(False, False) # 6. 设置窗口图标(需要.ico文件) root.iconbitmap("icon.ico") # 7. 让窗口始终置顶,可加按钮 root.attributes('-topmost', True) # 8. 设置窗口透明度(0.0-1.0 透明程度减弱) root.attributes('-alpha', 0.9) return root ``` 1. 设置窗口最顶部的标题栏文字 2. 设置窗口大小:宽400像素,高300像素("宽x高") 3. 设置窗口大小和位置:400x300("宽x高")是大小,+500+200(+距左边500像素+距顶部200像素)是位置 4. 设置窗口背景颜色 5. 是否拖拽边框改变大小 :宽度,高度 6. 设置窗口图标,需要图片文件 7. 窗口置顶,可加按钮选项 8. 窗口透明度,0.0-1.0 透明程度减弱 ### 2.3. 启动主循环 ```python import tkinter as tk def main(): """ 主程序函数 负责程序的整体流程控制 """ # 第1步:设置主窗口 root = setup_window() # 第2步:启动主循环,让窗口显示出来 root.mainloop() ``` - 启动事件循环,让窗口保持显示状态 - 这是必须的!没有这行代码,窗口会一闪而过 - ![窗口属性讲解示意图](png/21a6cdd98f264c7eb7c6850f976249a0.png) ## 3 GUI组件配置 **Label组件用于在窗口中显示文字或图像,是GUI中最基本的组件之一** ### 3.1 Label标签组件配置 ```python def create_label(root): """ 创建标签的函数 返回:配置好的标签对象 """ # 1. 创建标签(Label)对象 label = tk.Label(root, text="Hello, Tkinter!\n你好,Tkinter!", font=("Arial", 16, "bold"), # 加粗字体 bg="white", fg="black", justify="left", width=25, height=3) # 2. 使用 pack() 布局管理器放置标签 label.pack(pady=40, padx=40, fill="x") ``` - **Label 参数说明:** - `root`:父容器,这里就是我们的主窗口 - `text`:标签上显示的文本内容 - `font`:字体设置,格式为 (字体名称, 字号, "bold"加粗字体) - `bg`:背景颜色(background) - `fg`:前景色,即文字颜色(foreground) - `justify`:文本对齐方式, center居中, left左对齐, right右对齐 - `width`:标签宽度(字符数) - `height`:标签高度(字符数) --- - **pack 参数说明:** - `pady`:垂直方向的外边距(上下各 10 像素) - `padx`:水平方向的外边距(左右各 20 像素) - `fill="x"`:水平方向填充可用空间 - -- - 详细参考 [02_基础控件_标签Label.md](02_基础控件_标签Label.md) - ![标签.png](png/label.png) ### 3.2 Button按钮组件配置 ```python def create_button(root): """ 创建按钮的函数 返回:配置好的按钮对象 """ # 1. 创建按钮(Button)对象 button = tk.Button(root, text="点击我!\nClick Me!", font=("Arial", 14, "bold"), bg="lightgreen", fg="black", state="normal", width=15, height=2, relief="groove", cursor="hand2", command=lambda: print("按钮被点击了!")) # 2. 使用 pack() 布局管理器放置按钮 button.pack(pady=20, padx=40, fill="x") ``` - **Button 参数说明:** - `root`:父容器,这里就是我们的主窗口 - `text`:按钮上显示的文本内容 - `font`:字体设置,格式为 (字体名称, 字号, "bold"加粗字体) - `bg`:背景颜色(background) - `fg`:前景色,即文字颜色(foreground) - `state`:按钮状态,normal:正常,disabled:禁用 - `width`:按钮宽度(字符数) - `height`:按钮高度(字符数) - `relief`:边框样式: flat, raised, sunken, ridge, groove - `cursor`:鼠标悬停时显示的形状,如 "hand2" 表示小手 - `command`:点击按钮时执行的函数 --- - **pack 参数说明:** - `pady`:垂直方向的外边距(上下各 20 像素) - `padx`:水平方向的外边距(左右各 40 像素) - `fill="x"`:水平方向填充可用空间 - `side='left'`:从左到右依次排布 - 详细参考 [03_基础控件_按钮Button.md](03_基础控件_按钮Button.md) - ![按钮.png](png/button.png) ### 3.3 Entry输入框组件配置 ```python def create_entry(root): """ 创建输入框的函数 返回:配置好的输入框对象 """ # 1. 创建输入框(Entry)对象 entry = tk.Entry(root, width=30, font=("Arial", 11), fg="black", bg="lightcyan", relief="groove", bd=2, show="") # 密码框用 show="*" # 2. 设置提示文本 entry.insert(0, "请输入文本") # 3. 使用 pack() 布局管理器放置输入框 entry.pack(pady=10, padx=20) return entry ``` - **Entry 参数说明:** - `root`:父容器,这里就是我们的主窗口 - `width`:输入框的宽度(字符数) - `font`:字体设置,格式为 (字体名称, 字号) - `fg`:前景色,即文字颜色(foreground) - `bg`:背景颜色(background) - `relief`:边框样式: flat, raised, sunken, ridge, groove - `bd`:边框宽度 - `show`:隐藏输入内容(如密码框用 `show="*"`) --- - **Entry 常用方法:** - `entry.get()`:获取输入框中的文字 - `entry.insert(0, "文字")`:在输入框中插入文字 - `entry.delete(0, 'end')`:清空输入框 - `entry.config(state="disabled")`:禁用输入框 - 详细参考 [04_基础控件_输入框Entry.md](04_基础控件_输入框Entry.md) - ![输入框.png](png/entry.png) ### 3.4 Checkbutton复选框组件配置 ```python def create_checkbutton(root): """ 创建复选框的函数 返回:配置好的复选框对象 """ # 1. 创建布尔变量 var1 = tk.BooleanVar() # 2. 创建复选框(Checkbutton)对象 check1 = tk.Checkbutton(root, text="同意用户协议", variable=var1, font=("Arial", 12), bg="white", fg="black", selectcolor="lightblue", command=lambda: print(f"复选框状态: {var1.get()}")) # 3. 使用 pack() 布局管理器放置复选框 check1.pack(pady=10, padx=20, anchor="w") return check1, var1 ``` - **Checkbutton 参数说明:** - `root`:父容器,这里就是我们的主窗口 - `text`:复选框旁边显示的文本内容 - `variable`:关联的变量,通常是 BooleanVar() - `font`:字体设置,格式为 (字体名称, 字号) - `bg`:背景颜色(background) - `fg`:前景色,即文字颜色(foreground) - `selectcolor`:选中时的颜色 - `command`:点击复选框时执行的函数 --- - **Checkbutton 常用方法:** - `var1.get()`:获取复选框状态(True/False) - `var1.set(True)`:设置复选框为选中状态 - `check1.select()`:选中复选框 - `check1.deselect()`:取消选中复选框 - 详细参考 [07_选择控件_复选框Checkbutton.md](07_选择控件_复选框Checkbutton.md) - ![复选框.png](png/checkbutton.png) ### 3.5 Radiobutton单选按钮组件配置 ```python def create_radiobutton(root): """ 创建单选按钮的函数 返回:配置好的单选按钮对象 """ # 1. 创建字符串变量 var2 = tk.StringVar() var2.set("男") # 默认选择 # 2. 创建单选按钮(Radiobutton)对象 radio1 = tk.Radiobutton(root, text="男", variable=var2, value="男", font=("Arial", 12), bg="white", fg="black", selectcolor="lightgreen", command=lambda: print(f"选择了: {var2.get()}")) radio2 = tk.Radiobutton(root, text="女", variable=var2, value="女", font=("Arial", 12), bg="white", fg="black", selectcolor="lightgreen", command=lambda: print(f"选择了: {var2.get()}")) # 3. 使用 pack() 布局管理器放置单选按钮 radio1.pack(pady=5, padx=20, anchor="w") radio2.pack(pady=5, padx=20, anchor="w") return radio1, radio2, var2 ``` - **Radiobutton 参数说明:** - `root`:父容器,这里就是我们的主窗口 - `text`:单选按钮旁边显示的文本内容 - `variable`:关联的变量,通常是 StringVar() - `value`:该单选按钮的值 - `font`:字体设置,格式为 (字体名称, 字号) - `bg`:背景颜色(background) - `fg`:前景色,即文字颜色(foreground) - `selectcolor`:选中时的颜色 - `command`:点击单选按钮时执行的函数 --- - **Radiobutton 常用方法:** - `var2.get()`:获取当前选中的值 - `var2.set("选项1")`:设置选中指定的选项 - `radio1.select()`:选中该单选按钮 - `radio1.deselect()`:取消选中该单选按钮 - ![单选框.png](png/radiobutton.png) ### 3.6 Frame框架组件配置 ```python def create_frame(root): """ 创建框架的函数 返回:配置好的框架对象 """ # 1. 创建框架(Frame)对象 frame = tk.Frame(root, bg="lightblue", relief="ridge", bd=2, width=300, height=150) # 2. 使用 pack() 布局管理器放置框架 frame.pack(pady=10, padx=20, fill="x") # 3. 在框架中添加组件 label = tk.Label(frame, text="框架内的标签", bg="lightblue", font=("Arial", 12)) label.pack(pady=10) button = tk.Button(frame, text="框架内的按钮", bg="white", font=("Arial", 10)) button.pack(pady=5) return frame ``` - **Frame 参数说明:** - `root`:父容器,这里就是我们的主窗口 - `bg`:背景颜色(background) - `relief`:边框样式: flat, raised, sunken, ridge, groove - `bd`:边框宽度 - `width`:框架宽度(像素) - `height`:框架高度(像素) --- - **Frame 常用方法:** - `frame.pack()`:使用pack布局管理器 - `frame.grid()`:使用grid布局管理器 - `frame.place()`:使用place布局管理器 - `frame.config(bg="颜色")`:修改框架属性 - ![框架.png](png/frame.png) ### 3.7 Text文本框组件配置 ```python def create_text_widget(root): """ 创建多行文本框的函数 返回:配置好的文本框对象 """ # 1. 创建文本框(Text)对象 text_widget = tk.Text(root, width=40, height=10, font=("Arial", 12), bg="white", fg="black", relief="sunken", bd=2, wrap="word") # word: 按单词换行,char: 按字符换行 # 2. 插入初始文本 text_widget.insert("1.0", "这是一个多行文本框\n可以输入多行文本内容") # 3. 使用 pack() 布局管理器放置文本框 text_widget.pack(pady=10, padx=20, fill="both", expand=True) return text_widget ``` - **Text 参数说明:** - `root`:父容器,这里就是我们的主窗口 - `width`:文本框宽度(字符数) - `height`:文本框高度(行数) - `font`:字体设置,格式为 (字体名称, 字号) - `bg`:背景颜色(background) - `fg`:前景色,即文字颜色(foreground) - `relief`:边框样式: flat, raised, sunken, ridge, groove - `bd`:边框宽度 - `wrap`:换行方式,word:按单词换行,char:按字符换行 --- - **Text 常用方法:** - `text.get("1.0", "end")`:获取全部文本内容 - `text.insert("1.0", "文字")`:在开头插入文字 - `text.delete("1.0", "end")`:清空所有内容 - `text.config(state="disabled")`:禁用文本框编辑 - ![文本框.png](png/text.png) ### 3.8 Listbox列表框组件配置 ```python def create_listbox(root): """ 创建列表框的函数 返回:配置好的列表框对象 """ # 1. 创建列表框(Listbox)对象 listbox = tk.Listbox(root, width=30, height=8, font=("Arial", 11), bg="lightgray", fg="black", selectmode="single", # single: 单选, multiple: 多选 relief="sunken", bd=2) # 2. 添加列表项 items = ["苹果", "香蕉", "橙子", "葡萄", "草莓"] for item in items: listbox.insert("end", item) # 3. 使用 pack() 布局管理器放置列表框 listbox.pack(pady=10, padx=20) return listbox ``` - **Listbox 参数说明:** - `root`:父容器,这里就是我们的主窗口 - `width`:列表框宽度(字符数) - `height`:列表框高度(显示行数) - `font`:字体设置,格式为 (字体名称, 字号) - `bg`:背景颜色(background) - `fg`:前景色,即文字颜色(foreground) - `selectmode`:选择模式,single:单选,multiple:多选 - `relief`:边框样式: flat, raised, sunken, ridge, groove - `bd`:边框宽度 --- - **Listbox 常用方法:** - `listbox.get("active")`:获取当前选中项 - `listbox.curselection()`:获取所有选中项的索引 - `listbox.selection_set(0)`:设置选中第一项 - `listbox.delete(0)`:删除第一项 - `listbox.insert("end", "新项目")`:在末尾添加新项目 - ![列表框.png](png/listbox.png) ### 3.9 Scale滑动条组件配置 ```python def create_scale(root): """ 创建滑动条的函数 返回:配置好的滑动条对象 """ # 1. 创建滑动条(Scale)对象 scale = tk.Scale(root, from_=0, # 最小值 to=100, # 最大值 orient="horizontal", # horizontal: 水平, vertical: 垂直 length=300, # 长度(像素) tickinterval=20, # 刻度间隔 resolution=1, # 分辨率(步长) bg="lightblue", fg="black", highlightbackground="blue", label="音量调节") # 滑动条标签 # 2. 设置默认值 scale.set(50) # 3. 使用 pack() 布局管理器放置滑动条 scale.pack(pady=10, padx=20) return scale ``` - **Scale 参数说明:** - `root`:父容器,这里就是我们的主窗口 - `from_`:最小值 - `to`:最大值 - `orient`:方向,horizontal:水平,vertical:垂直 - `length`:长度(像素) - `tickinterval`:刻度间隔 - `resolution`:分辨率(步长) - `bg`:背景颜色(background) - `fg`:前景色,即文字颜色(foreground) - `label`:滑动条标签文字 --- - **Scale 常用方法:** - `scale.get()`:获取当前值 - `scale.set(75)`:设置值 - `scale.configure(state="disabled")`:禁用滑动条 - `scale.configure(state="normal")`:启用滑动条 - ![滑动条.png](png/scale.png) ### 3.10 Canvas画布组件配置 ```python def create_canvas(root): """ 创建画布的函数 返回:配置好的画布对象 """ # 1. 创建画布(Canvas)对象 canvas = tk.Canvas(root, width=300, height=200, bg="white", bd=2, relief="sunken") # 2. 在画布上绘制图形 canvas.create_line(10, 10, 290, 190, fill="red", width=2) canvas.create_oval(50, 50, 150, 150, fill="skyblue") canvas.create_rectangle(200, 50, 280, 100, fill="lightgreen", outline="blue") # 3. 使用 pack() 布局管理器放置画布 canvas.pack(pady=10, padx=20) return canvas ``` - **Canvas 参数说明:** - `root`:父容器,这里就是我们的主窗口 - `width`:画布宽度(像素) - `height`:画布高度(像素) - `bg`:背景颜色(background) - `bd`:边框宽度 - `relief`:边框样式: flat, raised, sunken, ridge, groove --- - **Canvas 常用方法:** - `canvas.create_line(x1, y1, x2, y2)`:绘制直线 - `canvas.create_oval(x1, y1, x2, y2)`:绘制椭圆 - `canvas.create_rectangle(x1, y1, x2, y2)`:绘制矩形 - `canvas.create_text(x, y, text="文字")`:绘制文字 - `canvas.delete("all")`:清空画布 - ![画布.png](png/canvas.png) ### 3.11 LabelFrame标签框架组件配置 ```python def create_labelframe(root): """ 创建标签框架的函数 返回:配置好的标签框架对象 """ # 1. 创建标签框架(LabelFrame)对象 labelframe = ttk.LabelFrame(root, text="LabelFrame 示例", padding=10) # 2. 在标签框架中添加组件 ttk.Label(labelframe, text="放在 LabelFrame 里的内容").pack() # 3. 使用 pack() 布局管理器放置标签框架 labelframe.pack(padx=15, pady=15, fill="x") return labelframe ``` - **LabelFrame 参数说明:** - `root`:父容器,这里就是我们的主窗口 - `text`:标签框架的标题文字 - `padding`:内边距 - `relief`:边框样式: flat, raised, sunken, ridge, groove - `bd`:边框宽度 --- - **LabelFrame 常用方法:** - `labelframe.pack()`:使用pack布局管理器 - `labelframe.grid()`:使用grid布局管理器 - `labelframe.config(text="新标题")`:修改标题文字 - ![标签框架.png](png/labelframe.png) ### 3.12 Toplevel子窗口组件配置 ```python def create_toplevel(root): """ 创建子窗口的函数 返回:配置好的子窗口对象 """ # 1. 创建子窗口(Toplevel)对象 top = tk.Toplevel(root) top.title("子窗口") top.geometry("300x300+500+200") top.transient(root) # 设置为临时窗口 top.grab_set() # 设置为模态窗口 # 2. 在子窗口中添加组件 tk.Label(top, text="I'm modal").pack(pady=20) return top ``` - **Toplevel 参数说明:** - `root`:父窗口对象 - `title`:子窗口标题 - `geometry`:窗口大小和位置 - `transient`:设置为临时窗口 - `grab_set`:设置为模态窗口 --- - **Toplevel 常用方法:** - `top.title("新标题")`:设置窗口标题 - `top.geometry("宽x高+x+y")`:设置窗口大小和位置 - `top.withdraw()`:隐藏窗口 - `top.deiconify()`:显示窗口 - `top.destroy()`:销毁窗口 - ![子窗口.png](png/toplevel.png) ### 3.13 Spinbox数字微调框组件配置 ```python def create_spinbox(root): """ 创建数字微调框的函数 返回:配置好的数字微调框对象 """ # 1. 创建数字微调框(Spinbox)对象 spinbox = ttk.Spinbox(root, from_=0, # 最小值 to=99, # 最大值 width=5, state="readonly") # readonly: 只读, normal: 可编辑 # 2. 设置默认值 spinbox.set(50) # 3. 使用 pack() 布局管理器放置数字微调框 spinbox.pack(pady=10, padx=20) return spinbox ``` - **Spinbox 参数说明:** - `root`:父容器,这里就是我们的主窗口 - `from_`:最小值 - `to`:最大值 - `width`:宽度(字符数) - `state`:状态,readonly:只读,normal:可编辑 - `increment`:步长值 --- - **Spinbox 常用方法:** - `spinbox.get()`:获取当前值 - `spinbox.set(75)`:设置值 - `spinbox.configure(state="disabled")`:禁用微调框 - `spinbox.configure(state="normal")`:启用微调框 - ![数字微调框.png](png/spinbox.png) ### 3.14 Combobox下拉框组件配置 ```python def create_combobox(root): """ 创建下拉框的函数 返回:配置好的下拉框对象 """ # 1. 创建下拉框(Combobox)对象 combobox = ttk.Combobox(root, values=["Apple", "Banana", "Cherry", "Date", "Elderberry"], state="readonly", # readonly: 只读, normal: 可编辑 width=15) # 2. 设置默认选中项 combobox.current(0) # 选中第一项 # 3. 使用 pack() 布局管理器放置下拉框 combobox.pack(pady=10, padx=20) return combobox ``` - **Combobox 参数说明:** - `root`:父容器,这里就是我们的主窗口 - `values`:下拉选项列表 - `state`:状态,readonly:只读,normal:可编辑 - `width`:宽度(字符数) - `font`:字体设置 --- - **Combobox 常用方法:** - `combobox.get()`:获取当前选中的值 - `combobox.set("新值")`:设置值 - `combobox.current(2)`:选中指定索引的项 - `combobox['values'] = ["新", "选项", "列表"]`:更新选项列表 - ![下拉框.png](png/combobox.png) ### 3.15 Progressbar进度条组件配置 ```python def create_progressbar(root): """ 创建进度条的函数 返回:配置好的进度条对象 """ # 1. 创建进度条(Progressbar)对象 progressbar = ttk.Progressbar(root, orient="horizontal", # horizontal: 水平, vertical: 垂直 length=250, mode="determinate") # determinate: 确定模式, indeterminate: 不确定模式 # 2. 设置进度值 progressbar["value"] = 40 # 设置进度为40% # 3. 使用 pack() 布局管理器放置进度条 progressbar.pack(pady=10, padx=20) return progressbar ``` - **Progressbar 参数说明:** - `root`:父容器,这里就是我们的主窗口 - `orient`:方向,horizontal:水平,vertical:垂直 - `length`:长度(像素) - `mode`:模式,determinate:确定模式,indeterminate:不确定模式 - `maximum`:最大值 --- - **Progressbar 常用方法:** - `progressbar["value"] = 50`:设置进度值 - `progressbar.start()`:开始不确定模式动画 - `progressbar.stop()`:停止不确定模式动画 - `progressbar.configure(mode="indeterminate")`:切换到不确定模式 - ![进度条.png](png/progressbar.png) ### 3.16 Menubutton菜单按钮组件配置 ```python def create_menubutton(root): """ 创建菜单按钮的函数 返回:配置好的菜单按钮对象 """ # 1. 创建菜单按钮(Menubutton)对象 menubutton = tk.Menubutton(root, text="File", relief="raised") # 2. 创建下拉菜单 menu = tk.Menu(menubutton, tearoff=0) menu.add_command(label="Open", command=lambda: print("open")) menu.add_command(label="Save", command=lambda: print("save")) menu.add_separator() menu.add_command(label="Exit", command=root.quit) # 3. 将菜单绑定到菜单按钮 menubutton.config(menu=menu) # 4. 使用 pack() 布局管理器放置菜单按钮 menubutton.pack(pady=10, padx=20) return menubutton ``` - **Menubutton 参数说明:** - `root`:父容器,这里就是我们的主窗口 - `text`:按钮上显示的文本 - `relief`:边框样式: flat, raised, sunken, ridge, groove - `menu`:关联的下拉菜单 - `direction`:菜单弹出方向 --- - **Menubutton 常用方法:** - `menubutton.config(menu=menu)`:设置关联菜单 - `menubutton.config(text="新文本")`:修改按钮文本 - `menubutton.invoke()`:程序化触发菜单 - ![菜单按钮.png](png/menubutton.png) ### 3.17 Menu菜单栏组件配置 ```python def create_menubar(root): """ 创建窗口菜单栏的函数 返回:配置好的菜单栏对象 """ # 1. 创建菜单栏(Menu)对象 menubar = tk.Menu(root) # 2. 创建文件菜单 filemenu = tk.Menu(menubar, tearoff=0) filemenu.add_command(label="New", command=lambda: print("New")) filemenu.add_command(label="Open", command=lambda: print("Open")) filemenu.add_command(label="Save", command=lambda: print("Save")) filemenu.add_separator() filemenu.add_command(label="Exit", command=root.quit) # 3. 创建编辑菜单 editmenu = tk.Menu(menubar, tearoff=0) editmenu.add_command(label="Cut", command=lambda: print("Cut")) editmenu.add_command(label="Copy", command=lambda: print("Copy")) editmenu.add_command(label="Paste", command=lambda: print("Paste")) # 4. 将子菜单添加到菜单栏 menubar.add_cascade(label="File", menu=filemenu) menubar.add_cascade(label="Edit", menu=editmenu) # 5. 将菜单栏设置到窗口 root.config(menu=menubar) return menubar ``` - **Menu 参数说明:** - `root`:父容器,这里就是我们的主窗口 - `tearoff`:是否允许拖拽分离菜单 - `label`:菜单项显示的文字 - `command`:菜单项被点击时执行的函数 --- - **Menu 常用方法:** - `menu.add_command()`:添加普通菜单项 - `menu.add_separator()`:添加分隔线 - `menu.add_cascade()`:添加子菜单 - `menu.add_checkbutton()`:添加复选框菜单项 - `menu.add_radiobutton()`:添加单选按钮菜单项 - ![菜单栏.png](png/menubar.png) ### 3.18 OptionMenu选项菜单组件配置 ```python def create_optionmenu(root): """ 创建选项菜单的函数 返回:配置好的选项菜单对象 """ # 1. 创建字符串变量 var = tk.StringVar(value="Python") # 2. 创建选项菜单(OptionMenu)对象 optionmenu = tk.OptionMenu(root, var, "Python", "C", "Java", "JavaScript", "Go") # 3. 使用 pack() 布局管理器放置选项菜单 optionmenu.pack(pady=10, padx=20) return optionmenu, var ``` - **OptionMenu 参数说明:** - `root`:父容器,这里就是我们的主窗口 - `variable`:关联的变量,通常是 StringVar() - `*options`:选项列表 - `command`:选择改变时执行的函数 --- - **OptionMenu 常用方法:** - `var.get()`:获取当前选中的值 - `var.set("新值")`:设置选中的值 - `optionmenu.config(command=callback)`:设置选择回调函数 - ![选项菜单.png](png/optionmenu.png) ### 3.19 Panedwindow分割面板组件配置 ```python def create_panedwindow(root): """ 创建可拖动分割面板的函数 返回:配置好的分割面板对象 """ # 1. 创建分割面板(Panedwindow)对象 panedwindow = ttk.Panedwindow(root, orient="horizontal") # 2. 创建左右两个面板 left = ttk.Frame(panedwindow, width=100, height=100, relief="sunken") right = ttk.Frame(panedwindow, width=100, height=100, relief="sunken") # 3. 在面板中添加内容 ttk.Label(left, text="左侧面板").pack(pady=20) ttk.Label(right, text="右侧面板").pack(pady=20) # 4. 将面板添加到分割面板 panedwindow.add(left, weight=1) panedwindow.add(right, weight=1) # 5. 使用 pack() 布局管理器放置分割面板 panedwindow.pack(fill="both", expand=True, pady=10, padx=20) return panedwindow ``` - **Panedwindow 参数说明:** - `root`:父容器,这里就是我们的主窗口 - `orient`:方向,horizontal:水平分割,vertical:垂直分割 - `sashwidth`:分割条宽度 - `sashrelief`:分割条样式 --- - **Panedwindow 常用方法:** - `panedwindow.add(widget, weight=1)`:添加面板 - `panedwindow.remove(widget)`:移除面板 - `panedwindow.paneconfig(widget, **options)`:配置面板属性 - ![分割面板.png](png/panedwindow.png) ### 3.20 Scrollbar滚动条组件配置 ```python def create_scrollbar(root): """ 创建滚动条的函数 返回:配置好的滚动条对象 """ # 1. 创建框架容器 frame = ttk.Frame(root) frame.pack(fill="both", expand=True, padx=10, pady=10) # 2. 创建文本框 text = tk.Text(frame, height=4, width=40) text.pack(side="left", fill="both", expand=True) # 3. 创建滚动条 scrollbar = ttk.Scrollbar(frame, orient="vertical", # vertical: 垂直, horizontal: 水平 command=text.yview) # 4. 配置文本框和滚动条的联动 scrollbar.pack(side="right", fill="y") text.config(yscrollcommand=scrollbar.set) # 5. 插入一些文本内容 text.insert("1.0", "这是一个带滚动条的文本框\n" * 20) return scrollbar ``` - **Scrollbar 参数说明:** - `root`:父容器,这里就是我们的主窗口 - `orient`:方向,vertical:垂直,horizontal:水平 - `command`:滚动时调用的函数 - `jump`:是否支持跳跃滚动 --- - **Scrollbar 常用方法:** - `scrollbar.set(first, last)`:设置滚动条位置 - `scrollbar.get()`:获取滚动条位置 - `scrollbar.configure(command=callback)`:设置滚动回调 - ![滚动条.png](png/scrollbar.png) ### 3.21 Separator分隔线组件配置 ```python def create_separator(root): """ 创建分隔线的函数 返回:配置好的分隔线对象 """ # 1. 创建分隔线(Separator)对象 separator = ttk.Separator(root, orient="horizontal") # horizontal: 水平, vertical: 垂直 # 2. 使用 pack() 布局管理器放置分隔线 separator.pack(fill="x", pady=10, padx=20) return separator ``` - **Separator 参数说明:** - `root`:父容器,这里就是我们的主窗口 - `orient`:方向,horizontal:水平,vertical:垂直 - `style`:分隔线样式 --- - **Separator 常用方法:** - `separator.pack()`:使用pack布局管理器 - `separator.grid()`:使用grid布局管理器 - `separator.configure(orient="vertical")`:修改方向 - ![分隔线.png](png/separator.png) ### 3.22 Sizegrip窗口缩放手柄组件配置 ```python def create_sizegrip(root): """ 创建窗口右下角缩放手柄的函数 返回:配置好的缩放手柄对象 """ # 1. 创建缩放手柄(Sizegrip)对象 sizegrip = ttk.Sizegrip(root) # 2. 使用 pack() 布局管理器放置缩放手柄 sizegrip.pack(side="right", anchor="se") return sizegrip ``` - **Sizegrip 参数说明:** - `root`:父容器,这里就是我们的主窗口 - `style`:缩放手柄样式 --- - **Sizegrip 常用方法:** - `sizegrip.pack(side="right", anchor="se")`:放置在右下角 - `sizegrip.grid(row=0, column=0, sticky="se")`:使用grid布局 - ![缩放手柄.png](png/sizegrip.png) ### 3.23 Treeview树形表格组件配置 ```python def create_treeview(root): """ 创建树形表格的函数 返回:配置好的树形表格对象 """ # 1. 创建树形表格(Treeview)对象 treeview = ttk.Treeview(root, columns=("size", "modified"), show="tree headings", # tree headings: 显示树和标题 height=4) # 2. 设置列标题 treeview.heading("#0", text="Name") treeview.heading("size", text="Size") treeview.heading("modified", text="Modified") # 3. 设置列宽度 treeview.column("#0", width=150) treeview.column("size", width=80) treeview.column("modified", width=100) # 4. 插入数据 treeview.insert("", "end", text="file.txt", values=("1 KB", "today")) treeview.insert("", "end", text="folder", values=("", "yesterday")) treeview.insert("folder", "end", text="subfile.txt", values=("500 B", "today")) # 5. 使用 pack() 布局管理器放置树形表格 treeview.pack(pady=10, padx=20, fill="both", expand=True) return treeview ``` - **Treeview 参数说明:** - `root`:父容器,这里就是我们的主窗口 - `columns`:列名列表 - `show`:显示模式,tree headings:显示树和标题 - `height`:显示行数 - `selectmode`:选择模式 --- - **Treeview 常用方法:** - `treeview.insert(parent, index, **options)`:插入项目 - `treeview.delete(item)`:删除项目 - `treeview.selection()`:获取选中项目 - `treeview.get_children(item)`:获取子项目 - ![树形表格.png](png/treeview.png) ### 3.24 Notebook标签页组件配置 ```python def create_notebook(root): """ 创建标签页控件的函数 返回:配置好的标签页对象 """ # 1. 创建标签页(Notebook)对象 notebook = ttk.Notebook(root) # 2. 创建标签页内容 tab1 = ttk.Frame(notebook) tab2 = ttk.Frame(notebook) tab3 = ttk.Frame(notebook) # 3. 在标签页中添加内容 ttk.Label(tab1, text="这是第一个标签页的内容").pack(pady=20) ttk.Label(tab2, text="这是第二个标签页的内容").pack(pady=20) ttk.Label(tab3, text="这是第三个标签页的内容").pack(pady=20) # 4. 添加标签页 notebook.add(tab1, text="Tab 1") notebook.add(tab2, text="Tab 2") notebook.add(tab3, text="Tab 3") # 5. 使用 pack() 布局管理器放置标签页 notebook.pack(fill="both", expand=True, padx=10, pady=10) return notebook ``` - **Notebook 参数说明:** - `root`:父容器,这里就是我们的主窗口 - `width`:宽度 - `height`:高度 - `padding`:内边距 --- - **Notebook 常用方法:** - `notebook.add(frame, text="标签名")`:添加标签页 - `notebook.remove(tab_id)`:移除标签页 - `notebook.select(tab_id)`:选择标签页 - `notebook.index(tab_id)`:获取标签页索引 - ![标签页.png](png/notebook.png) ### 3.25 Message消息组件配置 ```python def create_message(root): """ 创建消息组件的函数(已过时,仅示范) 返回:配置好的消息对象 """ # 1. 创建消息(Message)对象 message = tk.Message(root, text="This is a long text that will wrap automatically according to the width parameter.", width=200) # 2. 使用 pack() 布局管理器放置消息 message.pack(pady=10, padx=20) return message ``` - **Message 参数说明:** - `root`:父容器,这里就是我们的主窗口 - `text`:消息文本内容 - `width`:消息框宽度(像素) - `font`:字体设置 - `bg`:背景颜色 - `fg`:前景色 --- - **Message 常用方法:** - `message.config(text="新文本")`:修改消息文本 - `message.pack()`:使用pack布局管理器 - `message.grid()`:使用grid布局管理器 - ![消息.png](png/message.png) ### 3.26 MessageBox消息对话框组件配置 ```python def create_messagebox(root): """ 创建消息弹窗的函数(非控件) 返回:None """ # 1. 导入messagebox模块 from tkinter import messagebox # 2. 显示不同类型的消息框 messagebox.showinfo("信息", "这是一个信息对话框") messagebox.showwarning("警告", "这是一个警告对话框") messagebox.showerror("错误", "这是一个错误对话框") messagebox.askquestion("问题", "这是一个问题对话框") messagebox.askyesno("确认", "这是一个确认对话框") messagebox.askokcancel("确定取消", "这是一个确定取消对话框") ``` - **MessageBox 参数说明:** - `title`:对话框标题 - `message`:对话框消息内容 - `icon`:图标类型 - `type`:按钮类型 --- - **MessageBox 常用方法:** - `messagebox.showinfo(title, message)`:显示信息对话框 - `messagebox.showwarning(title, message)`:显示警告对话框 - `messagebox.showerror(title, message)`:显示错误对话框 - `messagebox.askquestion(title, message)`:显示问题对话框 - `messagebox.askyesno(title, message)`:显示是/否对话框 - `messagebox.askokcancel(title, message)`:显示确定/取消对话框 - ![消息对话框.png](png/messagebox.png) ### 3.27 ColorChooser颜色选择对话框组件配置 ```python def create_colorchooser(root): """ 创建颜色选择对话框的函数(非控件) 返回:None """ # 1. 导入colorchooser模块 from tkinter import colorchooser # 2. 显示颜色选择对话框 color = colorchooser.askcolor(title="选择颜色") if color[1]: # 如果用户选择了颜色 print(f"选择的颜色: {color[1]}") # color[0] 是RGB元组,color[1] 是十六进制颜色值 ``` - **ColorChooser 参数说明:** - `title`:对话框标题 - `color`:初始颜色 - `parent`:父窗口 --- - **ColorChooser 常用方法:** - `colorchooser.askcolor(title="选择颜色")`:显示颜色选择对话框 - 返回值:`(RGB元组, 十六进制颜色值)` 或 `(None, None)` - ![颜色选择器.png](png/colorchooser.png) ### 3.28 FileDialog文件对话框组件配置 ```python def create_filedialog(root): """ 创建文件选择对话框的函数(非控件) 返回:None """ # 1. 导入filedialog模块 from tkinter import filedialog # 2. 显示不同类型的文件对话框 # 打开文件对话框 filename = filedialog.askopenfilename( title="选择文件", filetypes=[("文本文件", "*.txt"), ("所有文件", "*.*")] ) # 保存文件对话框 filename = filedialog.asksaveasfilename( title="保存文件", defaultextension=".txt", filetypes=[("文本文件", "*.txt"), ("所有文件", "*.*")] ) # 选择目录对话框 directory = filedialog.askdirectory(title="选择目录") # 打开多个文件对话框 filenames = filedialog.askopenfilenames( title="选择多个文件", filetypes=[("文本文件", "*.txt"), ("所有文件", "*.*")] ) ``` - **FileDialog 参数说明:** - `title`:对话框标题 - `filetypes`:文件类型过滤器 - `defaultextension`:默认文件扩展名 - `initialdir`:初始目录 - `parent`:父窗口 --- - **FileDialog 常用方法:** - `filedialog.askopenfilename()`:显示打开文件对话框 - `filedialog.asksaveasfilename()`:显示保存文件对话框 - `filedialog.askdirectory()`:显示选择目录对话框 - `filedialog.askopenfilenames()`:显示选择多个文件对话框 - ![文件对话框.png](png/filedialog.png) ## 5 简单交互功能 ### 5.1 按钮点击事件处理 ```python def create_interactive_buttons(root): """ 创建具有交互功能的按钮 返回:按钮和标签组件 """ # 1. 创建显示标签 result_label = tk.Label(root, text="计数器: 0", font=("Arial", 14), bg="white", fg="blue") result_label.pack(pady=10) # 2. 创建计数器变量 counter = tk.IntVar(value=0) # 3. 定义按钮事件处理函数 def increase_count(): counter.set(counter.get() + 1) result_label.config(text=f"计数器: {counter.get()}") def decrease_count(): counter.set(counter.get() - 1) result_label.config(text=f"计数器: {counter.get()}") def reset_count(): counter.set(0) result_label.config(text="计数器: 0") # 4. 创建按钮组件 inc_button = tk.Button(root, text="增加 +1", command=increase_count, bg="lightgreen", font=("Arial", 12), width=10) inc_button.pack(pady=5) dec_button = tk.Button(root, text="减少 -1", command=decrease_count, bg="lightcoral", font=("Arial", 12), width=10) dec_button.pack(pady=5) reset_button = tk.Button(root, text="重置", command=reset_count, bg="lightyellow", font=("Arial", 12), width=10) reset_button.pack(pady=5) return result_label, inc_button, dec_button, reset_button ``` - **交互功能说明:** - 使用 `tk.IntVar()` 创建整数变量来存储计数器值 - 通过 `command` 参数绑定按钮点击事件 - 使用 `label.config()` 方法动态更新标签文本 - 每个按钮都有独立的事件处理函数 - ![交互.png](png/interactive_buttons.png) ### 5.2 输入框与按钮联动 ```python def create_input_interaction(root): """ 创建输入框与按钮的交互功能 返回:输入框和相关组件 """ # 1. 创建输入框 entry = tk.Entry(root, width=30, font=("Arial", 12), bg="lightyellow", relief="groove", bd=2) entry.pack(pady=10) entry.insert(0, "请输入文本内容...") # 2. 创建显示标签 display_label = tk.Label(root, text="输入内容将显示在这里", font=("Arial", 12), bg="white", fg="green", relief="sunken", bd=1, width=40, height=2) display_label.pack(pady=10) # 3. 定义交互事件处理函数 def show_input(): text = entry.get() if text and text != "请输入文本内容...": display_label.config(text=f"你输入了: {text}") else: display_label.config(text="请先输入内容!") def clear_input(): entry.delete(0, 'end') entry.insert(0, "请输入文本内容...") display_label.config(text="输入内容已清空") # 4. 创建操作按钮 show_button = tk.Button(root, text="显示输入", command=show_input, bg="lightblue", font=("Arial", 12), width=12) show_button.pack(pady=5) clear_button = tk.Button(root, text="清空内容", command=clear_input, bg="lightcoral", font=("Arial", 12), width=12) clear_button.pack(pady=5) return entry, display_label, show_button, clear_button ``` - **联动功能说明:** - 使用 `entry.get()` 获取输入框内容 - 使用 `entry.delete()` 和 `entry.insert()` 清空和设置输入框 - 通过条件判断处理空输入的情况 - 实时更新显示标签的文本内容 - ![联动.png](png/input_interaction.png) ### 5.3 复选框状态监控 ```python def create_checkbox_monitor(root): """ 创建复选框状态监控功能 返回:复选框和状态标签组件 """ # 1. 创建状态显示标签 status_label = tk.Label(root, text="爱好选择: 未选中任何项目", font=("Arial", 12), bg="lightcyan", fg="blue", relief="groove", bd=2, width=35, height=2) status_label.pack(pady=10) # 2. 创建复选框变量 check_var1 = tk.BooleanVar() check_var2 = tk.BooleanVar() check_var3 = tk.BooleanVar() # 3. 定义状态更新函数 def update_status(): hobbies = [] if check_var1.get(): hobbies.append("读书") if check_var2.get(): hobbies.append("运动") if check_var3.get(): hobbies.append("音乐") if hobbies: status_label.config(text=f"你的爱好: {' + '.join(hobbies)}") else: status_label.config(text="爱好选择: 未选中任何项目") # 4. 创建复选框组件 check1 = tk.Checkbutton(root, text="📚 读书", variable=check_var1, command=update_status, font=("Arial", 11), bg="white") check1.pack(pady=3, anchor="w", padx=50) check2 = tk.Checkbutton(root, text="🏃 运动", variable=check_var2, command=update_status, font=("Arial", 11), bg="white") check2.pack(pady=3, anchor="w", padx=50) check3 = tk.Checkbutton(root, text="🎵 音乐", variable=check_var3, command=update_status, font=("Arial", 11), bg="white") check3.pack(pady=3, anchor="w", padx=50) return status_label, check1, check2, check3 ``` - **状态监控说明:** - 每个复选框都绑定了相同的 `command` 函数 - 使用 `BooleanVar.get()` 检查复选框状态 - 动态组合选中项目的文本显示 - 实时反映用户的选择状态 - ![复选框联动.png](png/checkbox_monitor.png) ## 6 容器与布局管理 ### 6.1 Frame容器组件应用 ```python def create_frame_containers(root): """ 创建多个Frame容器来组织界面 返回:各个框架组件 """ # 1. 创建顶部Frame - 标题区域 top_frame = tk.Frame(root, bg="lightblue", relief="raised", bd=2, height=60) top_frame.pack(fill="x", padx=10, pady=5) title_label = tk.Label(top_frame, text="📋 用户信息管理系统", font=("Arial", 16, "bold"), bg="lightblue", fg="darkblue") title_label.pack(pady=15) # 2. 创建中间Frame - 主要内容区域 main_frame = tk.Frame(root, bg="lightgray", relief="sunken", bd=2) main_frame.pack(fill="both", expand=True, padx=10, pady=5) # 3. 在main_frame中创建左右两个子Frame left_frame = tk.Frame(main_frame, bg="white", relief="ridge", bd=1, width=200) left_frame.pack(side="left", fill="both", expand=True, padx=5, pady=5) right_frame = tk.Frame(main_frame, bg="white", relief="ridge", bd=1, width=200) right_frame.pack(side="right", fill="both", expand=True, padx=5, pady=5) # 4. 左侧Frame内容 tk.Label(left_frame, text="👤 用户信息", bg="white", font=("Arial", 12, "bold")).pack(pady=10) tk.Button(left_frame, text="添加用户", bg="lightgreen", width=12).pack(pady=5) tk.Button(left_frame, text="编辑用户", bg="lightyellow", width=12).pack(pady=5) # 5. 右侧Frame内容 tk.Label(right_frame, text="📊 数据统计", bg="white", font=("Arial", 12, "bold")).pack(pady=10) tk.Button(right_frame, text="查看报表", bg="lightcoral", width=12).pack(pady=5) tk.Button(right_frame, text="导出数据", bg="lightcyan", width=12).pack(pady=5) # 6. 创建底部Frame - 状态栏 bottom_frame = tk.Frame(root, bg="lightyellow", relief="groove", bd=2, height=30) bottom_frame.pack(fill="x", padx=10, pady=5) status_label = tk.Label(bottom_frame, text="✅ 状态: 系统就绪", bg="lightyellow", font=("Arial", 10)) status_label.pack(pady=5) return top_frame, main_frame, left_frame, right_frame, bottom_frame ``` - **Frame容器布局说明:** - 使用多个Frame组件将界面分割成不同区域 - `pack()` 的 `fill` 和 `expand` 参数控制组件填充方式 - `side` 参数控制组件的排列方向 - 通过嵌套Frame实现复杂的布局结构 - ![布局管理.png](png/frame_containers.png) ### 6.2 布局管理器详解 #### 6.2.1 pack() 布局管理器详解 ```python def demonstrate_pack_layout(root): """ 演示pack布局管理器的各种参数 返回:演示框架和按钮组件 """ # 1. 创建演示Frame demo_frame = tk.Frame(root, bg="white", relief="ridge", bd=2, width=400, height=300) demo_frame.pack(fill="both", expand=True, padx=20, pady=20) # 2. 顶部按钮 - 水平填充 top_button = tk.Button(demo_frame, text="🔝 顶部按钮 (水平填充)", bg="lightblue", font=("Arial", 10)) top_button.pack(fill="x", padx=10, pady=5) # 3. 左侧按钮组 left_frame = tk.Frame(demo_frame, bg="lightgreen", width=100) left_frame.pack(side="left", fill="y", padx=10, pady=10) tk.Button(left_frame, text="⬅️ 左1", bg="lightgreen", width=8).pack(pady=2) tk.Button(left_frame, text="⬅️ 左2", bg="lightgreen", width=8).pack(pady=2) tk.Button(left_frame, text="⬅️ 左3", bg="lightgreen", width=8).pack(pady=2) # 4. 右侧按钮组 right_frame = tk.Frame(demo_frame, bg="lightcoral", width=100) right_frame.pack(side="right", fill="y", padx=10, pady=10) tk.Button(right_frame, text="右1 ➡️", bg="lightcoral", width=8).pack(pady=2) tk.Button(right_frame, text="右2 ➡️", bg="lightcoral", width=8).pack(pady=2) tk.Button(right_frame, text="右3 ➡️", bg="lightcoral", width=8).pack(pady=2) # 5. 底部按钮 - 水平填充 bottom_button = tk.Button(demo_frame, text="🔽 底部按钮 (水平填充)", bg="lightyellow", font=("Arial", 10)) bottom_button.pack(side="bottom", fill="x", padx=10, pady=5) return demo_frame, top_button, left_frame, right_frame, bottom_button ``` - **pack() 参数详解:** - `side`:指定组件放置的边,"top"(默认)、"bottom"、"left"、"right" - `fill`:填充方向,"x"(水平)、"y"(垂直)、"both"(双向) - `expand`:是否随窗口大小变化而扩展,True/False - `padx`、`pady`:外边距,水平和垂直方向的间距 - `anchor`:对齐方式,"n"、"s"、"e"、"w"、"center"等 - ![布局管理.png](png/demonstrate_pack_layout.png) #### 6.2.2 grid() 布局管理器详解 ```python def demonstrate_grid_layout(root): """ 演示grid布局管理器的网格布局 返回:演示框架和网格按钮 """ # 1. 创建演示Frame demo_frame = tk.Frame(root, bg="white", relief="ridge", bd=2, width=500, height=350) demo_frame.pack(fill="both", expand=True, padx=20, pady=20) # 2. 使用grid布局创建3x3网格 buttons = [] for i in range(3): row_buttons = [] for j in range(3): button = tk.Button(demo_frame, text=f"📍({i},{j})", width=10, height=3, bg="lightblue", font=("Arial", 9)) button.grid(row=i, column=j, padx=2, pady=2, sticky="nsew") row_buttons.append(button) buttons.append(row_buttons) # 3. 配置行列权重,使网格能够扩展 for i in range(3): demo_frame.grid_rowconfigure(i, weight=1) demo_frame.grid_columnconfigure(i, weight=1) # 4. 添加跨越多个网格的组件 wide_button = tk.Button(demo_frame, text="📏 跨越两列的按钮", bg="lightgreen", height=2, font=("Arial", 10)) wide_button.grid(row=3, column=0, columnspan=2, sticky="ew", padx=2, pady=2) tall_button = tk.Button(demo_frame, text="📐\n跨\n越\n两\n行", bg="lightcoral", width=8, font=("Arial", 9)) tall_button.grid(row=1, column=3, rowspan=2, sticky="ns", padx=2, pady=2) return demo_frame, buttons, wide_button, tall_button ``` - **grid() 参数详解:** - `row`、`column`:指定组件在网格中的行和列位置 - `rowspan`、`columnspan`:跨越的行数和列数 - `sticky`:组件在网格单元中的对齐方式,"n"、"s"、"e"、"w"的组合 - `padx`、`pady`:外边距 - `grid_rowconfigure()`、`grid_columnconfigure()`:配置行列权重 - ![布局管理.png](png/demonstrate_grid_layout.png) #### 6.2.3 place() 布局管理器详解 ```python def demonstrate_place_layout(root): """ 演示place布局管理器的绝对定位 返回:演示框架和定位按钮 """ # 1. 创建演示Frame demo_frame = tk.Frame(root, bg="white", relief="ridge", bd=2, width=450, height=300) demo_frame.pack(fill="both", expand=True, padx=20, pady=20) demo_frame.pack_propagate(False) # 防止Frame被内容撑大 # 2. 使用绝对坐标定位按钮 button1 = tk.Button(demo_frame, text="🏠 左上角", bg="lightblue", width=12, font=("Arial", 9)) button1.place(x=20, y=20) button2 = tk.Button(demo_frame, text="🌟 右上角", bg="lightgreen", width=12, font=("Arial", 9)) button2.place(relx=1.0, x=-130, y=20, anchor="ne") button3 = tk.Button(demo_frame, text="📍 左下角", bg="lightcoral", width=12, font=("Arial", 9)) button3.place(x=20, rely=1.0, y=-50, anchor="sw") button4 = tk.Button(demo_frame, text="🎯 右下角", bg="lightyellow", width=12, font=("Arial", 9)) button4.place(relx=1.0, rely=1.0, x=-130, y=-50, anchor="se") # 3. 居中按钮 center_button = tk.Button(demo_frame, text="⭐ 正中心", bg="lightgray", width=12, height=2, font=("Arial", 10, "bold")) center_button.place(relx=0.5, rely=0.5, anchor="center") # 4. 相对位置按钮 relative_button = tk.Button(demo_frame, text="🔄 相对位置", bg="lightpink", width=12, font=("Arial", 9)) relative_button.place(relx=0.3, rely=0.7, anchor="center") return demo_frame, button1, button2, button3, button4, center_button, relative_button ``` - **place() 参数详解:** - `x`、`y`:绝对坐标位置(像素) - `relx`、`rely`:相对坐标位置(0.0-1.0) - `width`、`height`:组件的绝对大小 - `relwidth`、`relheight`:组件的相对大小(0.0-1.0) - `anchor`:锚点位置,决定组件相对于指定位置的对齐方式 - ![布局管理.png](png/demonstrate_place_layout.png) ## 7 事件处理机制 ### 7.1 鼠标事件处理 ```python def create_mouse_events(root): """ 创建鼠标事件处理示例 返回:事件标签和测试区域 """ # 1. 创建事件显示标签 event_label = tk.Label(root, text="🖱️ 鼠标事件: 等待操作", font=("Arial", 12), bg="lightyellow", fg="blue", relief="groove", bd=2, width=40, height=2) event_label.pack(pady=10) # 2. 创建鼠标事件测试区域 test_frame = tk.Frame(root, bg="lightblue", width=350, height=200, relief="ridge", bd=3) test_frame.pack(pady=10) test_frame.pack_propagate(False) # 防止Frame被内容撑大 # 3. 定义鼠标事件处理函数 def on_mouse_enter(event): event_label.config(text="🖱️ 鼠标事件: 进入测试区域") test_frame.config(bg="lightgreen") def on_mouse_leave(event): event_label.config(text="🖱️ 鼠标事件: 离开测试区域") test_frame.config(bg="lightblue") def on_mouse_click(event): event_label.config(text=f"🖱️ 鼠标事件: 点击位置 ({event.x}, {event.y})") test_frame.config(bg="lightcoral") # 4. 绑定鼠标事件 test_frame.bind("", on_mouse_enter) # 鼠标进入 test_frame.bind("", on_mouse_leave) # 鼠标离开 test_frame.bind("", on_mouse_click) # 左键点击 # 5. 添加说明文字 info_label = tk.Label(root, text="💡 提示:在蓝色区域移动、点击鼠标查看事件效果", font=("Arial", 10), fg="gray") info_label.pack(pady=5) return event_label, test_frame, info_label ``` - **鼠标事件类型:** - ``:鼠标进入组件区域 - ``:鼠标离开组件区域 - ``:鼠标左键点击 - ``:鼠标右键点击 - ``:鼠标移动(会频繁触发) - ![布局管理.png](png/mouse_events.png) ### 7.2 键盘事件处理 ```python def create_keyboard_events(root): """ 创建键盘事件处理示例 返回:事件标签和输入框 """ # 1. 创建事件显示标签 event_label = tk.Label(root, text="⌨️ 键盘事件: 等待按键", font=("Arial", 12), bg="lightcyan", fg="darkgreen", relief="groove", bd=2, width=40, height=2) event_label.pack(pady=10) # 2. 创建输入框用于接收键盘事件 entry = tk.Entry(root, width=40, font=("Arial", 12), bg="white", relief="sunken", bd=2) entry.pack(pady=10) entry.insert(0, "在此输入文字测试键盘事件...") # 3. 定义键盘事件处理函数 def on_key_press(event): key = event.keysym char = event.char if char and char.isprintable(): event_label.config(text=f"⌨️ 键盘事件: 按下字符 '{char}' (键码: {key})") else: event_label.config(text=f"⌨️ 键盘事件: 按下特殊键 [{key}]") # 4. 绑定键盘事件 entry.bind("", on_key_press) entry.focus_set() # 设置输入框获得焦点 # 5. 添加说明文字 info_label = tk.Label(root, text="💡 提示:在输入框中输入文字或按特殊键(如方向键、回车等)", font=("Arial", 10), fg="gray") info_label.pack(pady=5) return event_label, entry, info_label ``` - **键盘事件类型:** - ``:按键按下事件 - ``:按键释放事件 - ``:回车键事件 - ``:Tab键事件 - ``:退格键事件 - ![布局管理.png](png/keyboard_events.png)