📖 Tkinter 是 Python 标准库中自带的图形用户界面(GUI)开发工具,无需额外安装,是 Python 桌面应用开发的首选入门框架。
1. Tkinter简介
1.1 什么是Tkinter
Tkinter 是 Python 内置的 GUI(图形用户界面)编程框架,它是 Tcl/Tk 工具包的 Python 绑定。
1.2 Tkinter的优势
| 特性 | 说明 |
|---|---|
| ✅ 无需安装 | Python 3.x 内置,随装随用 |
| ✅ 跨平台 | Windows、macOS、Linux 全支持 |
| ✅ 学习曲线平缓 | API 简洁直观,半小时入门 |
| ✅ 功能完整 | 满足大多数桌面应用需求 |
| ✅ 轻量级 | 内存占用小,启动快速 |
1.3 Tkinter能做什么
| 应用场景 | 说明 |
|---|---|
| 📝 桌面工具 | 记事本、计算器、文件管理器等 |
| 📊 数据可视化 | 图表展示、数据报表工具 |
| 🎮 小游戏 | 扫雷、贪吃蛇、五子棋等 |
| 📁 文件管理器 | 文件浏览、批量重命名工具 |
| 📋 表单应用 | 登录界面、注册页面、信息录入 |
| 🔧 系统配置 | 设置面板、参数配置工具 |
| 📅 计划任务 | 待办事项、日程管理、提醒工具 |
| 💬 聊天界面 | 简易聊天室、消息通知窗口 |
2. 环境准备
2.1 检查Tkinter是否可用
import tkinter as tk
# 检查Tkinter版本
print(f"Tkinter版本: {tk.TkVersion}")
# 检查ttk主题支持
try:
from tkinter import ttk
print("ttk主题组件: 已安装")
except ImportError:
print("ttk主题组件: 未安装")
2.2 安装Pillow(用于图片处理)
# 安装Pillow用于处理图片
pip install pillow
2.3 环境验证代码
import tkinter as tk
from tkinter import messagebox
def test_environment():
"""测试Tkinter环境是否正常"""
try:
root = tk.Tk()
root.withdraw() # 隐藏测试窗口
messagebox.showinfo(
"环境测试",
"🎉 Tkinter环境配置成功!\n\n可以开始GUI编程了。"
)
root.destroy()
return True
except Exception as e:
messagebox.showerror("错误", f"环境配置失败:\n{e}")
return False
if __name__ == "__main__":
test_environment()
3. 第一个GUI程序
3.1 最简单的窗口
import tkinter as tk
# 创建主窗口
window = tk.Tk()
# 设置窗口标题
window.title("我的第一个GUI程序")
# 设置窗口大小
window.geometry("400x300")
# 运行主循环(显示窗口)
window.mainloop()
运行效果:
运行后会弹出一个空白窗口,标题为”我的第一个GUI程序”,大小为400×300像素。
3.2 带组件的窗口
import tkinter as tk
# 创建主窗口
window = tk.Tk()
window.title("Hello Tkinter")
window.geometry("300x200")
# 创建标签组件
label = tk.Label(
window,
text="Hello, Tkinter! 🖥️",
font=("Arial", 20),
fg="blue"
)
label.pack(pady=50) # pack() 将组件添加到窗口,pady设置上下间距
# 创建按钮
def on_click():
label.config(text="按钮被点击了!🎉")
button = tk.Button(
window,
text="点我",
command=on_click,
bg="#4CAF50",
fg="white",
width=10
)
button.pack()
# 运行主循环
window.mainloop()
运行效果:
![图片[1]-Python 进阶教程:Tkinter GUI 图形界面编程-小程博客](https://www.zenly.ink/wp-content/uploads/2026/05/f772f71fd820260515104938.png)
实际运行效果如上图所示,包含一个标题为”Hello Tkinter”的窗口,显示蓝色标题文本和绿色按钮。
3.3 程序结构解析
import tkinter as tk # 1️⃣ 导入tkinter模块
def create_window():
# 2️⃣ 创建主窗口
window = tk.Tk()
# 3️⃣ 配置窗口
window.title("窗口标题")
window.geometry("800x600")
# 4️⃣ 创建组件
label = tk.Label(window, text="Hello")
button = tk.Button(window, text="Click")
# 5️⃣ 使用布局管理器放置组件
label.pack()
button.pack()
# 6️⃣ 进入主循环
window.mainloop()
if __name__ == "__main__":
create_window()
4. 窗口基础配置
4.1 常用窗口属性
| 属性/方法 | 说明 | 示例 |
|---|---|---|
title() | 设置窗口标题 | window.title("标题") |
geometry() | 设置窗口大小和位置 | window.geometry("800x600") |
resizable() | 设置是否可调整大小 | window.resizable(False, False) |
maxsize() | 设置最大尺寸 | window.maxsize(1024, 768) |
minsize() | 设置最小尺寸 | window.minsize(400, 300) |
configure(bg=) | 设置背景颜色 | window.configure(bg="white") |
iconify() | 最小化窗口 | window.iconify() |
state('zoomed') | 全屏/最大化 | window.state('zoomed') |
withdraw() | 隐藏窗口 | window.withdraw() |
deiconify() | 显示窗口 | window.deiconify() |
4.2 窗口配置示例
import tkinter as tk
window = tk.Tk()
# 设置窗口标题
window.title("高级窗口配置")
# 设置窗口大小和位置: "宽x高+x偏移+y偏移"
window.geometry("800x600+100+100")
# 设置窗口是否可调整大小 (宽可调, 高可调)
window.resizable(True, True)
# 设置最大最小尺寸
window.minsize(400, 300)
window.maxsize(1920, 1080)
# 设置窗口透明度 (0.0-1.0)
window.attributes('-alpha', 0.95)
# 设置窗口图标
try:
window.iconbitmap('app.ico')
except:
pass # 图标文件不存在时跳过
# 设置窗口背景色
window.configure(bg='#f0f0f0')
window.mainloop()
运行效果:
运行后会弹出一个配置完整的窗口,包含标题、大小限制、透明度等设置。
4.3 居中显示窗口
import tkinter as tk
def center_window(window, width, height):
"""将窗口居中显示"""
screen_width = window.winfo_screenwidth()
screen_height = window.winfo_screenheight()
x = (screen_width - width) // 2
y = (screen_height - height) // 2
window.geometry(f"{width}x{height}+{x}+{y}")
# 使用示例
window = tk.Tk()
window.title("居中窗口")
# 创建400x300的居中窗口
center_window(window, 400, 300)
window.mainloop()
5. 常用组件
5.1 组件一览表
| 组件 | 英文名称 | 功能说明 |
|---|---|---|
| 标签 | Label | 显示静态文本或图片 |
| 按钮 | Button | 创建可点击按钮 |
| 单行输入 | Entry | 用户输入单行文本 |
| 多行文本 | Text | 输入或显示多行文本 |
| 框架容器 | Frame | 组织和分组其他组件 |
| 复选框 | Checkbutton | 多选选项 |
| 单选框 | Radiobutton | 互斥选择 |
| 列表框 | Listbox | 显示项目列表 |
| 画布 | Canvas | 绘制图形、线条和图片 |
| 滑块 | Scale | 范围值选择 |
| 下拉框 | Combobox | 下拉选择列表 |
| 微调框 | Spinbox | 数值微调选择 |
5.2 Label(标签)
用于显示文本或图片。
import tkinter as tk
window = tk.Tk()
window.title("Label组件演示")
window.geometry("400x300")
# 基础文本标签
lbl_basic = tk.Label(
window,
text="这是一个普通标签",
font=("微软雅黑", 12)
)
lbl_basic.pack(pady=10)
# 彩色标签
lbl_color = tk.Label(
window,
text="彩色文本标签",
font=("Arial", 14, "bold"),
fg="white",
bg="#2196F3", # 蓝色背景
padx=20,
pady=10
)
lbl_color.pack(pady=10)
# 带图片的标签
try:
photo = tk.PhotoImage(file="python_logo.png")
lbl_image = tk.Label(window, image=photo)
lbl_image.pack(pady=10)
except:
lbl_image = tk.Label(window, text="[Python Logo]")
lbl_image.pack(pady=10)
# 多行文本标签
lbl_multiline = tk.Label(
window,
text="第一行\n第二行\n第三行",
justify="left", # 左对齐
relief=tk.RAISED, # 边框样式
borderwidth=2
)
lbl_multiline.pack(pady=10)
window.mainloop()
运行效果:
![图片[2]-Python 进阶教程:Tkinter GUI 图形界面编程-小程博客](https://www.zenly.ink/wp-content/uploads/2026/05/bcd93ef49a20260515105028.png)
上图展示了四种不同的Label样式:普通文本标签、蓝色背景彩色标签、带边框标签和SUNKEN凹入效果标签。
5.3 Button(按钮)
用于响应用户点击事件。
import tkinter as tk
from tkinter import messagebox
def on_click():
messagebox.showinfo("提示", "按钮被点击了!")
def on_hover(e):
btn2.config(text="鼠标悬停中...")
def on_leave(e):
btn2.config(text="悬停按钮")
window = tk.Tk()
window.title("Button组件演示")
window.geometry("400x300")
# 普通按钮
btn1 = tk.Button(
window,
text="普通按钮",
command=on_click,
width=15,
height=2
)
btn1.pack(pady=10)
# 带样式的按钮
btn2 = tk.Button(
window,
text="悬停按钮",
font=("微软雅黑", 12),
bg="#4CAF50",
fg="white",
activebackground="#45a049",
activeforeground="white",
relief=tk.RAISED,
bd=3
)
btn2.pack(pady=10)
btn2.bind("<Enter>", on_hover)
btn2.bind("<Leave>", on_leave)
# 禁用状态的按钮
btn3 = tk.Button(
window,
text="禁用按钮",
state=tk.DISABLED,
width=15
)
btn3.pack(pady=10)
# 带图标的按钮
try:
photo = tk.PhotoImage(file="icon.png")
btn4 = tk.Button(window, image=photo, width=50, height=30)
btn4.pack(pady=10)
except:
btn4 = tk.Button(window, text="[图标按钮]", width=15)
btn4.pack(pady=10)
window.mainloop()
运行效果:
![图片[3]-Python 进阶教程:Tkinter GUI 图形界面编程-小程博客](https://www.zenly.ink/wp-content/uploads/2026/05/11edc23f6520260515105038.png)
上图展示了四种Button状态:普通按钮、绿色样式按钮、红色样式按钮和禁用状态按钮(灰色不可点击)。
5.4 Entry(单行输入框)
用于用户输入单行文本。
import tkinter as tk
from tkinter import messagebox
def get_input():
text = entry.get()
messagebox.showinfo("输入内容", f"你输入了: {text}")
def clear_input():
entry.delete(0, tk.END)
def show_password():
if show_var.get():
entry.config(show="")
else:
entry.config(show="*")
window = tk.Tk()
window.title("Entry组件演示")
window.geometry("400x250")
# 标签
tk.Label(window, text="用户名:", font=("Arial", 12)).pack(pady=5)
# 普通输入框
entry = tk.Entry(window, width=30, font=("Arial", 12))
entry.insert(0, "请输入用户名")
entry.pack(pady=5)
# 密码输入框
tk.Label(window, text="密码:", font=("Arial", 12)).pack(pady=5)
# 密码显示切换
show_var = tk.BooleanVar()
chk_show = tk.Checkbutton(
window,
text="显示密码",
variable=show_var,
command=show_password
)
chk_show.pack()
# 创建密码输入框
entry_password = tk.Entry(window, width=30, font=("Arial", 12), show="*")
entry_password.pack(pady=5)
# 按钮组
btn_frame = tk.Frame(window)
btn_frame.pack(pady=15)
tk.Button(btn_frame, text="获取输入", command=get_input).pack(side=tk.LEFT, padx=5)
tk.Button(btn_frame, text="清空", command=clear_input).pack(side=tk.LEFT, padx=5)
window.mainloop()
运行效果:
![图片[4]-Python 进阶教程:Tkinter GUI 图形界面编程-小程博客](https://www.zenly.ink/wp-content/uploads/2026/05/4693aefca720260515105116.png)
上图展示了Entry输入框组件,包括用户名输入框(明文显示)和密码输入框(密文显示),以及登录按钮。
5.5 Text(多行文本框)
用于输入或显示多行文本。
import tkinter as tk
from tkinter import scrolledtext
def save_content():
content = text_area.get("1.0", tk.END)
with open("notes.txt", "w", encoding="utf-8") as f:
f.write(content)
status.config(text="✅ 保存成功!")
def clear_content():
text_area.delete("1.0", tk.END)
status.config(text="已清空")
window = tk.Tk()
window.title("Text组件演示")
window.geometry("450x350")
# 创建带滚动条的文本区域
text_area = scrolledtext.ScrolledText(
window,
width=50,
height=15,
font=("Consolas", 11),
wrap=tk.WORD,
undo=True # 支持撤销
)
text_area.pack(pady=10, padx=10, fill=tk.BOTH, expand=True)
# 添加一些初始文本
text_area.insert("1.0", "# 我的笔记\n\n这是一个多行文本编辑器...\n")
# 按钮栏
btn_frame = tk.Frame(window)
btn_frame.pack(pady=5)
tk.Button(btn_frame, text="保存", command=save_content, width=10).pack(side=tk.LEFT, padx=5)
tk.Button(btn_frame, text="清空", command=clear_content, width=10).pack(side=tk.LEFT, padx=5)
# 状态栏
status = tk.Label(window, text="就绪", relief=tk.SUNKEN, anchor=tk.W)
status.pack(fill=tk.X, padx=5, pady=5)
window.mainloop()
运行效果:
![图片[5]-Python 进阶教程:Tkinter GUI 图形界面编程-小程博客](https://www.zenly.ink/wp-content/uploads/2026/05/a1c05d7df720260515105125.png)
上图展示了ScrolledText多行文本编辑器组件,带有滚动条,支持保存和清空功能。
5.6 Frame(框架容器)
用于组织和分组其他组件。
import tkinter as tk
window = tk.Tk()
window.title("Frame组件演示")
window.geometry("500x300")
# 创建主Frame(白色背景)
main_frame = tk.Frame(window, bg="#ffffff", relief=tk.RAISED, bd=2)
main_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)
# 标题
tk.Label(
main_frame,
text="用户注册表单",
font=("微软雅黑", 16, "bold"),
bg="#ffffff"
).pack(pady=10)
# 创建左侧Frame(用户名区域)
left_frame = tk.Frame(main_frame, bg="#f5f5f5", relief=tk.SUNKEN, bd=1)
left_frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=5, pady=5)
tk.Label(left_frame, text="用户名", bg="#f5f5f5").pack(pady=5)
tk.Entry(left_frame, width=20).pack(pady=5)
tk.Label(left_frame, text="邮箱", bg="#f5f5f5").pack(pady=5)
tk.Entry(left_frame, width=20).pack(pady=5)
# 创建右侧Frame(密码区域)
right_frame = tk.Frame(main_frame, bg="#f5f5f5", relief=tk.SUNKEN, bd=1)
right_frame.pack(side=tk.RIGHT, fill=tk.BOTH, expand=True, padx=5, pady=5)
tk.Label(right_frame, text="密码", bg="#f5f5f5").pack(pady=5)
tk.Entry(right_frame, width=20, show="*").pack(pady=5)
tk.Label(right_frame, text="确认密码", bg="#f5f5f5").pack(pady=5)
tk.Entry(right_frame, width=20, show="*").pack(pady=5)
# 底部按钮
tk.Button(main_frame, text="注册", width=10, bg="#4CAF50", fg="white").pack(pady=15)
window.mainloop()
运行效果:
![图片[6]-Python 进阶教程:Tkinter GUI 图形界面编程-小程博客](https://www.zenly.ink/wp-content/uploads/2026/05/2bbb0cad8f20260515105139.png)
上图展示了Frame框架容器的使用,左侧蓝色区域为”基本信息”,右侧绿色区域为”安全信息”,中间有注册按钮。
5.7 Checkbutton(复选框)和 Radiobutton(单选框)
import tkinter as tk
from tkinter import messagebox
def show_selection():
# 获取复选框状态
checks = []
if var_accept.get():
checks.append("✅ 接受协议")
# 获取单选框状态
gender = gender_var.get()
result = f"复选框: {', '.join(checks) if checks else '未接受'}\n"
result += f"性别: {gender}"
messagebox.showinfo("选择结果", result)
window = tk.Tk()
window.title("复选框和单选框演示")
window.geometry("350x300")
# 复选框区域
check_frame = tk.LabelFrame(window, text="兴趣爱好", padx=10, pady=10)
check_frame.pack(pady=10, padx=10, fill=tk.X)
var_hobby1 = tk.BooleanVar()
var_hobby2 = tk.BooleanVar()
var_hobby3 = tk.BooleanVar()
tk.Checkbutton(check_frame, text="编程 💻", variable=var_hobby1).pack(anchor=tk.W)
tk.Checkbutton(check_frame, text="阅读 📚", variable=var_hobby2).pack(anchor=tk.W)
tk.Checkbutton(check_frame, text="音乐 🎵", variable=var_hobby3).pack(anchor=tk.W)
# 单选框区域
radio_frame = tk.LabelFrame(window, text="性别", padx=10, pady=10)
radio_frame.pack(pady=10, padx=10, fill=tk.X)
gender_var = tk.StringVar(value="未知")
tk.Radiobutton(radio_frame, text="男 🧑", variable=gender_var, value="男").pack(anchor=tk.W)
tk.Radiobutton(radio_frame, text="女 👩", variable=gender_var, value="女").pack(anchor=tk.W)
tk.Radiobutton(radio_frame, text="保密 🙈", variable=gender_var, value="保密").pack(anchor=tk.W)
# 协议复选框
var_accept = tk.BooleanVar()
tk.Checkbutton(window, text="我已阅读并同意用户协议", variable=var_accept).pack(pady=10)
# 提交按钮
tk.Button(window, text="提交", command=show_selection, width=15).pack(pady=10)
window.mainloop()
运行效果:
![图片[7]-Python 进阶教程:Tkinter GUI 图形界面编程-小程博客](https://www.zenly.ink/wp-content/uploads/2026/05/366adfd17320260515105149.png)
上图展示了复选框(Checkbutton,可多选)和单选框(Radiobutton,互斥选择)的使用效果。
5.8 Listbox(列表框)
import tkinter as tk
from tkinter import Listbox, END, ANCHOR
def add_item():
item = entry.get()
if item:
listbox.insert(END, item)
entry.delete(0, END)
def delete_item():
try:
index = listbox.curselection()[0]
listbox.delete(index)
except:
pass
def show_selected(event):
try:
index = listbox.curselection()[0]
selected = listbox.get(index)
lbl_selected.config(text=f"已选择: {selected}")
except:
pass
window = tk.Tk()
window.title("Listbox组件演示")
window.geometry("300x350")
# 输入区域
frame_top = tk.Frame(window)
frame_top.pack(pady=10)
entry = tk.Entry(frame_top, width=20)
entry.pack(side=tk.LEFT, padx=5)
tk.Button(frame_top, text="添加", command=add_item, width=6).pack(side=tk.LEFT)
# 列表框
listbox = Listbox(window, width=35, height=12, font=("Arial", 11))
listbox.pack(pady=10)
# 预填充一些项目
fruits = ["苹果 🍎", "香蕉 🍌", "橙子 🍊", "葡萄 🍇", "草莓 🍓"]
for fruit in fruits:
listbox.insert(END, fruit)
listbox.bind("<<ListboxSelect>>", show_selected)
# 操作按钮
btn_frame = tk.Frame(window)
btn_frame.pack(pady=5)
tk.Button(btn_frame, text="删除", command=delete_item, width=8).pack(side=tk.LEFT, padx=5)
# 显示选择结果
lbl_selected = tk.Label(window, text="已选择: ", font=("Arial", 10))
lbl_selected.pack(pady=5)
window.mainloop()
运行效果:
![图片[8]-Python 进阶教程:Tkinter GUI 图形界面编程-小程博客](https://www.zenly.ink/wp-content/uploads/2026/05/277acf1dbc20260515105201.png)
上图展示了Listbox列表框组件,显示水果列表,支持选择和删除操作。
5.9 Canvas(画布)
用于绘制图形、线条和图片。
import tkinter as tk
window = tk.Tk()
window.title("Canvas组件演示")
window.geometry("400x350")
canvas = tk.Canvas(window, width=380, height=280, bg="white", relief=tk.SUNKEN, bd=2)
canvas.pack(pady=10)
# 绘制矩形
canvas.create_rectangle(20, 20, 120, 80, fill="#FF6B6B", outline="#D63031", width=2)
# 绘制椭圆
canvas.create_oval(150, 20, 250, 80, fill="#74B9FF", outline="#0984E3", width=2)
# 绘制多边形(三角形)
canvas.create_polygon(270, 80, 320, 80, 295, 30, fill="#55EFC4", outline="#00B894")
# 绘制文字
canvas.create_text(70, 50, text="矩形", font=("Arial", 12, "bold"), fill="white")
canvas.create_text(200, 50, text="椭圆", font=("Arial", 12, "bold"), fill="white")
# 绘制线条
canvas.create_line(20, 120, 120, 200, fill="#A29BFE", width=3)
canvas.create_line(120, 120, 20, 200, fill="#A29BFE", width=3)
# 绘制弧形
canvas.create_arc(150, 120, 250, 220, start=0, extent=180, fill="#FDCB6E")
# 绘制笑脸
canvas.create_oval(320, 130, 370, 180, fill="#FFEAA7", outline="black", width=1)
canvas.create_oval(330, 145, 340, 155, fill="black") # 左眼
canvas.create_oval(350, 145, 360, 155, fill="black") # 右眼
canvas.create_arc(330, 155, 360, 175, start=0, extent=-180, fill="black") # 微笑
# 绘制网格线
for i in range(30, 380, 30):
canvas.create_line(i, 220, i, 270, fill="#ddd")
for i in range(220, 280, 25):
canvas.create_line(30, i, 380, i, fill="#ddd")
# 绘制进度条背景
canvas.create_rectangle(30, 230, 380, 250, fill="#eee", outline="#ddd")
canvas.create_rectangle(30, 230, 200, 250, fill="#00B894", outline="")
# 添加标注
canvas.create_text(200, 265, text="进度: 60%", font=("Arial", 10), anchor=tk.CENTER)
window.mainloop()
运行效果:
![图片[9]-Python 进阶教程:Tkinter GUI 图形界面编程-小程博客](https://www.zenly.ink/wp-content/uploads/2026/05/5ab830786a20260515105209.png)
上图展示了Canvas画布组件的绘图能力,包括矩形、椭圆、三角形、线条、弧形、笑脸和进度条。
5.10 Scale(滑块)和 Spinbox(微调框)
import tkinter as tk
from tkinter import ttk
def on_scale_change(value):
lbl_scale.config(text=f"滑块值: {int(float(value))}")
def on_spin_change():
lbl_spin.config(text=f"微调值: {spin_var.get()}")
window = tk.Tk()
window.title("Scale和Spinbox演示")
window.geometry("350x300")
# Scale(滑块)演示
scale_frame = tk.LabelFrame(window, text="滑块组件", padx=10, pady=10)
scale_frame.pack(pady=10, padx=10, fill=tk.X)
lbl_scale = tk.Label(scale_frame, text="滑块值: 50", font=("Arial", 12))
lbl_scale.pack()
scale = ttk.Scale(
scale_frame,
from_=0,
to=100,
orient=tk.HORIZONTAL,
command=on_scale_change
)
scale.set(50) # 设置默认值
scale.pack(fill=tk.X, pady=5)
# Spinbox(微调框)演示
spin_frame = tk.LabelFrame(window, text="微调框组件", padx=10, pady=10)
spin_frame.pack(pady=10, padx=10, fill=tk.X)
lbl_spin = tk.Label(spin_frame, text="微调值: 0", font=("Arial", 12))
lbl_spin.pack()
spin_var = tk.IntVar(value=0)
spinbox = ttk.Spinbox(
spin_frame,
from_=-50,
to=50,
textvariable=spin_var,
command=on_spin_change,
width=15
)
spinbox.pack(pady=5)
# 数值选择Spinbox
tk.Label(spin_frame, text="选择数量:").pack(pady=5)
spin2 = ttk.Spinbox(spin_frame, from_=1, to=100, width=15)
spin2.pack()
window.mainloop()
运行效果:
![图片[10]-Python 进阶教程:Tkinter GUI 图形界面编程-小程博客](https://www.zenly.ink/wp-content/uploads/2026/05/0abc84f8ac20260515105217.png)
上图展示了Scale滑块组件(用于音量调节等连续值选择)和Spinbox微调框组件(用于数值选择)。
6. 布局管理器
6.1 三大布局管理器对比
| 布局管理器 | 说明 | 适用场景 |
|---|---|---|
pack() | 按顺序堆叠组件 | 简单垂直/水平排列 |
grid() | 网格行列布局 | 表格、表单等对齐布局 |
place() | 精确坐标定位 | 需要精确控制位置的场景 |
6.2 pack() 布局
import tkinter as tk
window = tk.Tk()
window.title("pack()布局演示")
window.geometry("400x400")
# pack的side参数
top_frame = tk.Frame(window, bg="#FF6B6B", width=400, height=80)
top_frame.pack(side=tk.TOP, fill=tk.X)
tk.Label(top_frame, text="顶部区域 - TOP", bg="#FF6B6B", fg="white", font=("Arial", 14)).pack(pady=20)
# 中间区域
middle_frame = tk.Frame(window, bg="#4ECDC4", width=400, height=80)
middle_frame.pack(side=tk.TOP, fill=tk.X, pady=5)
tk.Label(middle_frame, text="中间区域", bg="#4ECDC4", fg="white", font=("Arial", 14)).pack(pady=20)
# 底部区域使用expand
bottom_frame = tk.Frame(window, bg="#45B7D1")
bottom_frame.pack(side=tk.TOP, fill=tk.BOTH, expand=True)
# fill参数演示
btn_frame = tk.Frame(bottom_frame, bg="#96CEB4")
btn_frame.pack(pady=10, padx=20, fill=tk.X)
tk.Button(btn_frame, text="填充X").pack(side=tk.LEFT, padx=5, fill=tk.X, expand=True)
tk.Button(btn_frame, text="填充X").pack(side=tk.LEFT, padx=5, fill=tk.X, expand=True)
tk.Button(btn_frame, text="填充X").pack(side=tk.LEFT, padx=5, fill=tk.X, expand=True)
window.mainloop()
运行效果:
pack()布局会按顺序堆叠组件,支持TOP/BOTTOM/LEFT/RIGHT四个方向,以及fill和expand参数控制填充行为。
6.3 grid() 布局
import tkinter as tk
window = tk.Tk()
window.title("grid()布局演示")
window.geometry("450x400")
# 创建表单布局
labels = ["姓名:", "邮箱:", "电话:", "地址:", "城市:", "邮编:"]
entries = ["张伟", "zhang@example.com", "13800138000", "北京市朝阳区", "北京", "100000"]
for i, (label_text, default_value) in enumerate(zip(labels, entries)):
tk.Label(window, text=label_text, font=("Arial", 12)).grid(
row=i, column=0, sticky=tk.E, padx=10, pady=8
)
entry = tk.Entry(window, width=30, font=("Arial", 12))
entry.insert(0, default_value)
entry.grid(row=i, column=1, padx=10, pady=8)
# 设置列权重,使Entry列可以扩展
window.columnconfigure(1, weight=1)
# 按钮区域
btn_frame = tk.Frame(window)
btn_frame.grid(row=7, column=0, columnspan=2, pady=20)
tk.Button(btn_frame, text="提交", width=10, bg="#4CAF50", fg="white").pack(side=tk.LEFT, padx=10)
tk.Button(btn_frame, text="取消", width=10).pack(side=tk.LEFT, padx=10)
window.mainloop()
运行效果:
grid()布局将窗口划分为行和列的网格,适合表单等需要对齐的布局场景。
6.4 place() 布局
import tkinter as tk
window = tk.Tk()
window.title("place()布局演示")
window.geometry("400x300")
# 使用place精确放置组件
canvas = tk.Canvas(window, width=380, height=200, bg="#f0f0f0", relief=tk.SUNKEN)
canvas.pack(pady=10)
# 绘制一个简单的登录界面布局
# 用户名标签
canvas.create_text(80, 40, text="用户名:", font=("Arial", 12), anchor=tk.E)
# 用户名输入框
canvas.create_rectangle(90, 25, 280, 55, fill="white", outline="gray")
canvas.create_text(100, 40, text="请输入用户名", fill="gray")
# 密码标签
canvas.create_text(80, 90, text="密码:", font=("Arial", 12), anchor=tk.E)
# 密码输入框
canvas.create_rectangle(90, 75, 280, 105, fill="white", outline="gray")
canvas.create_text(100, 90, text="••••••••", fill="gray")
# 登录按钮
canvas.create_rectangle(140, 130, 220, 165, fill="#4CAF50", outline="#388E3C")
canvas.create_text(180, 147, text="登录", font=("Arial", 12, "bold"), fill="white")
# 说明文本
canvas.create_text(190, 190, text="place() 使用 x,y 坐标精确定位", font=("Arial", 9), fill="#666")
window.mainloop()
运行效果:
place()布局使用精确的(x, y)坐标定位组件,适合需要精确控制位置的场景。
7. 事件处理
7.1 事件类型一览
| 事件类型 | 说明 | 示例 |
|---|---|---|
<Button-1> | 鼠标左键点击 | 按钮点击 |
<Button-2> | 鼠标中键点击 | 滚轮点击 |
<Button-3> | 鼠标右键点击 | 右键菜单 |
<Double-Button-1> | 双击 | Listbox双击 |
<Enter> | 鼠标进入 | 悬停效果 |
<Leave> | 鼠标离开 | 悬停效果 |
<Key> | 键盘按键 | 全局键盘事件 |
<KeyPress> | 按键按下 | 同上 |
<FocusIn> | 获得焦点 | 输入框焦点 |
<FocusOut> | 失去焦点 | 输入验证 |
<Return> | 回车键 | 表单提交 |
<Escape> | ESC键 | 取消操作 |
7.2 事件绑定示例
import tkinter as tk
from tkinter import messagebox
def on_key_press(event):
lbl_key.config(text=f"按键: {event.char} (键码: {event.keycode})")
def on_click(event):
x, y = event.x, event.y
canvas.create_oval(x-5, y-5, x+5, y+5, fill="#FF6B6B")
lbl_pos.config(text=f"点击位置: ({x}, {y})")
def on_right_click(event):
canvas.delete("all") # 清空画布
lbl_pos.config(text="画布已清空")
window = tk.Tk()
window.title("事件处理演示")
window.geometry("450x350")
# 键盘事件区域
key_frame = tk.LabelFrame(window, text="键盘事件", padx=10, pady=5)
key_frame.pack(pady=5, padx=10, fill=tk.X)
lbl_key = tk.Label(key_frame, text="请按下任意键...", font=("Arial", 11))
lbl_key.pack()
# 画布演示鼠标事件
canvas = tk.Canvas(window, width=430, height=200, bg="white", relief=tk.SUNKEN)
canvas.pack(pady=5, padx=10)
# 鼠标点击事件
canvas.bind("<Button-1>", on_click)
# 右键清空
canvas.bind("<Button-3>", on_right_click)
# 右键菜单
def show_context_menu(event):
menu.post(event.x_root, event.y_root)
menu = tk.Menu(window, tearoff=0)
menu.add_command(label="清空", command=lambda: canvas.delete("all"))
menu.add_command(label="撤销", command=lambda: canvas.delete(canvas.find_all()[-1]))
menu.add_separator()
menu.add_command(label="退出", command=window.quit)
canvas.bind("<Button-3>", show_context_menu)
# 位置显示
lbl_pos = tk.Label(window, text="点击位置: (-, -)", relief=tk.SUNKEN)
lbl_pos.pack(pady=5)
# 全局键盘监听
window.bind("<Key>", on_key_press)
window.focus_set() # 获取焦点以便接收键盘事件
window.mainloop()
运行效果:
事件处理演示展示了键盘事件监听和鼠标点击事件,点击画布会在对应位置绘制圆点。
7.3 组件command参数
import tkinter as tk
from tkinter import messagebox
def on_click():
messagebox.showinfo("提示", "按钮被点击!")
def on_focus_in(event):
event.widget.config(bg="#E3F2FD")
def on_focus_out(event):
event.widget.config(bg="white")
window = tk.Tk()
window.title("command参数演示")
window.geometry("350x250")
# Button的command参数
tk.Button(window, text="点击我", command=on_click, width=15).pack(pady=10)
# Entry的focus事件
tk.Label(window, text="输入框焦点事件:").pack(pady=5)
entry = tk.Entry(window, width=25, font=("Arial", 12))
entry.pack()
entry.bind("<FocusIn>", on_focus_in)
entry.bind("<FocusOut>", on_focus_out)
# 计数器示例
counter = [0]
def update_counter():
counter[0] += 1
lbl_counter.config(text=f"计数器: {counter[0]}")
tk.Button(window, text="计数+1", command=update_counter, width=15).pack(pady=10)
lbl_counter = tk.Label(window, text="计数器: 0", font=("Arial", 14))
lbl_counter.pack()
window.mainloop()
8. 高级组件
8.1 Combobox(下拉框)
import tkinter as tk
from tkinter import ttk
def on_select(event):
selected = combo.get()
lbl_result.config(text=f"选择: {selected}")
window = tk.Tk()
window.title("Combobox演示")
window.geometry("300x200")
tk.Label(window, text="选择一个编程语言:", font=("Arial", 12)).pack(pady=10)
# 创建Combobox
combo = ttk.Combobox(window, width=20, font=("Arial", 12))
combo['values'] = ("Python", "Java", "JavaScript", "C++", "Go", "Rust")
combo.current(0) # 设置默认值
combo.pack(pady=10)
combo.bind("<<ComboboxSelected>>", on_select)
lbl_result = tk.Label(window, text="选择: Python", font=("Arial", 14))
lbl_result.pack(pady=20)
window.mainloop()
8.2 Treeview(树形视图)
import tkinter as tk
from tkinter import ttk
window = tk.Tk()
window.title("Treeview演示")
window.geometry("400x350")
# 创建Treeview
tree = ttk.Treeview(window, columns=("姓名", "年龄", "城市"), show="headings", height=10)
tree.pack(pady=10)
# 设置列
tree.heading("姓名", text="姓名")
tree.heading("年龄", text="年龄")
tree.heading("城市", text="城市")
tree.column("姓名", width=120, anchor=tk.CENTER)
tree.column("年龄", width=80, anchor=tk.CENTER)
tree.column("城市", width=120, anchor=tk.CENTER)
# 添加数据
data = [
("张伟", "28", "北京"),
("李娜", "25", "上海"),
("王强", "32", "深圳"),
("刘芳", "27", "广州"),
]
for person in data:
tree.insert("", tk.END, values=person)
# 添加按钮
def add_row():
tree.insert("", tk.END, values=("新增", "30", "新城市"))
def delete_row():
selected = tree.selection()
if selected:
tree.delete(selected)
btn_frame = tk.Frame(window)
btn_frame.pack(pady=10)
tk.Button(btn_frame, text="添加", command=add_row, width=8).pack(side=tk.LEFT, padx=5)
tk.Button(btn_frame, text="删除", command=delete_row, width=8).pack(side=tk.LEFT, padx=5)
window.mainloop()
运行效果:
![图片[11]-Python 进阶教程:Tkinter GUI 图形界面编程-小程博客](https://www.zenly.ink/wp-content/uploads/2026/05/9d39b2a7f920260515105320.png)
上图展示了Treeview树形视图组件,以表格形式展示数据(姓名、年龄、城市),支持添加和删除操作。
8.3 Notebook(选项卡)
import tkinter as tk
from tkinter import ttk
window = tk.Tk()
window.title("Notebook选项卡演示")
window.geometry("400x300")
# 创建Notebook
notebook = ttk.Notebook(window)
notebook.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)
# 第一个选项卡
tab1 = tk.Frame(notebook, bg="#E8F5E9")
notebook.add(tab1, text="📊 数据")
tk.Label(tab1, text="数据分析内容", font=("Arial", 14), bg="#E8F5E9").pack(pady=30)
# 第二个选项卡
tab2 = tk.Frame(notebook, bg="#E3F2FD")
notebook.add(tab2, text="📈 图表")
tk.Label(tab2, text="图表展示内容", font=("Arial", 14), bg="#E3F2FD").pack(pady=30)
# 第三个选项卡
tab3 = tk.Frame(notebook, bg="#FFF3E0")
notebook.add(tab3, text="⚙️ 设置")
tk.Label(tab3, text="系统设置内容", font=("Arial", 14), bg="#FFF3E0").pack(pady=30)
window.mainloop()
运行效果:
![图片[12]-Python 进阶教程:Tkinter GUI 图形界面编程-小程博客](https://www.zenly.ink/wp-content/uploads/2026/05/99085ef61820260515105330.png)
上图展示了Notebook选项卡组件,包含”数据统计”、”图表展示”和”系统设置”三个选项卡。
9. 菜单与对话框
9.1 创建菜单栏
import tkinter as tk
from tkinter import messagebox, filedialog
def new_file():
messagebox.showinfo("菜单", "新建文件")
def open_file():
filename = filedialog.askopenfilename(
title="选择文件",
filetypes=[("文本文件", "*.txt"), ("所有文件", "*.*")]
)
if filename:
messagebox.showinfo("打开", f"选择了: {filename}")
def save_file():
messagebox.save_openfilename = filedialog.asksaveasfilename(
title="保存文件",
defaultextension=".txt",
filetypes=[("文本文件", "*.txt"), ("所有文件", "*.*")]
)
window = tk.Tk()
window.title("菜单栏演示")
window.geometry("400x300")
# 创建菜单栏
menubar = tk.Menu(window)
window.config(menu=menubar)
# 文件菜单
file_menu = tk.Menu(menubar, tearoff=0)
menubar.add_cascade(label="文件", menu=file_menu)
file_menu.add_command(label="新建", command=new_file, accelerator="Ctrl+N")
file_menu.add_command(label="打开", command=open_file, accelerator="Ctrl+O")
file_menu.add_command(label="保存", command=save_file, accelerator="Ctrl+S")
file_menu.add_separator()
file_menu.add_command(label="退出", command=window.quit)
# 编辑菜单
edit_menu = tk.Menu(menubar, tearoff=0)
menubar.add_cascade(label="编辑", menu=edit_menu)
edit_menu.add_command(label="撤销")
edit_menu.add_command(label="重做")
edit_menu.add_separator()
edit_menu.add_command(label="剪切")
edit_menu.add_command(label="复制")
edit_menu.add_command(label="粘贴")
# 帮助菜单
help_menu = tk.Menu(menubar, tearoff=0)
menubar.add_cascade(label="帮助", menu=help_menu)
help_menu.add_command(label="关于", command=lambda: messagebox.showinfo("关于", "Tkinter教程 v1.0"))
help_menu.add_command(label="使用手册")
window.mainloop()
运行效果:
![图片[13]-Python 进阶教程:Tkinter GUI 图形界面编程-小程博客](https://www.zenly.ink/wp-content/uploads/2026/05/fa9958586920260515105435.png)
上图展示了菜单栏(Menu)组件,包含”文件”、”编辑”和”帮助”三个菜单项。
9.2 消息对话框
import tkinter as tk
from tkinter import messagebox
window = tk.Tk()
window.title("对话框演示")
window.geometry("350x250")
def show_info():
messagebox.showinfo("信息", "这是一条信息提示!")
def show_warning():
messagebox.showwarning("警告", "这是一个警告信息!")
def show_error():
messagebox.showerror("错误", "发生了一个错误!")
def ask_yesno():
result = messagebox.askyesno("确认", "确定要继续吗?")
lbl_result.config(text=f"结果: {result}")
def ask_okcancel():
result = messagebox.askokcancel("提示", "操作不可逆,确定吗?")
lbl_result.config(text=f"结果: {result}")
tk.Button(window, text="信息框", command=show_info, width=15).pack(pady=5)
tk.Button(window, text="警告框", command=show_warning, width=15).pack(pady=5)
tk.Button(window, text="错误框", command=show_error, width=15).pack(pady=5)
tk.Button(window, text="是/否对话框", command=ask_yesno, width=15).pack(pady=5)
tk.Button(window, text="确定/取消对话框", command=ask_okcancel, width=15).pack(pady=5)
lbl_result = tk.Label(window, text="结果: -", font=("Arial", 11))
lbl_result.pack(pady=15)
window.mainloop()
运行效果:
![图片[14]-Python 进阶教程:Tkinter GUI 图形界面编程-小程博客](https://www.zenly.ink/wp-content/uploads/2026/05/e6d1e9cb2e20260515105502.png)
上图展示了四种常用的消息对话框:信息框、警告框、错误框和确认对话框。
9.3 文件对话框
import tkinter as tk
from tkinter import filedialog, colorchooser
def open_file():
filename = filedialog.askopenfilename(
title="打开文件",
initialdir="/",
filetypes=[
("文本文件", "*.txt"),
("Python文件", "*.py"),
("所有文件", "*.*")
]
)
if filename:
lbl_file.config(text=f"打开: {filename}")
def save_file():
filename = filedialog.asksaveasfilename(
title="保存文件",
defaultextension=".txt",
filetypes=[
("文本文件", "*.txt"),
("所有文件", "*.*")
]
)
if filename:
lbl_file.config(text=f"保存: {filename}")
def choose_color():
color = colorchooser.askcolor(title="选择颜色")
if color[1]:
lbl_file.config(text=f"颜色: {color[1]}", fg=color[1])
window = tk.Tk()
window.title("文件对话框演示")
window.geometry("400x200")
tk.Button(window, text="打开文件", command=open_file, width=20).pack(pady=10)
tk.Button(window, text="保存文件", command=save_file, width=20).pack(pady=10)
tk.Button(window, text="选择颜色", command=choose_color, width=20).pack(pady=10)
lbl_file = tk.Label(window, text="请选择操作", font=("Arial", 11))
lbl_file.pack(pady=20)
window.mainloop()
10. 面向对象编程
10.1 基于类的窗口
import tkinter as tk
from tkinter import messagebox
class MyWindow:
def __init__(self, master):
self.master = master
self.master.title("OOP窗口示例")
self.master.geometry("300x200")
self.create_widgets()
def create_widgets(self):
self.label = tk.Label(
self.master,
text="面向对象窗口",
font=("Arial", 16)
)
self.label.pack(pady=20)
self.button = tk.Button(
self.master,
text="点击我",
command=self.on_click
)
self.button.pack(pady=10)
self.entry = tk.Entry(self.master, width=20)
self.entry.pack(pady=10)
def on_click(self):
text = self.entry.get() or "世界"
messagebox.showinfo("问候", f"你好, {text}!")
# 使用
root = tk.Tk()
app = MyWindow(root)
root.mainloop()
10.2 多页面应用
import tkinter as tk
class MultiPageApp:
def __init__(self, master):
self.master = master
self.master.title("多页面应用")
self.master.geometry("400x300")
# 创建容器Frame
self.container = tk.Frame(self.master)
self.container.pack(fill=tk.BOTH, expand=True)
# 创建各个页面
self.page1 = self.create_page1()
self.page2 = self.create_page2()
self.page3 = self.create_page3()
# 默认显示第一页
self.show_page(self.page1)
# 导航按钮
self.create_nav()
def create_page1(self):
frame = tk.Frame(self.container, bg="#E3F2FD")
tk.Label(frame, text="📊 数据统计页面", font=("Arial", 18), bg="#E3F2FD").pack(pady=50)
tk.Label(frame, text="这是数据统计模块", bg="#E3F2FD").pack()
return frame
def create_page2(self):
frame = tk.Frame(self.container, bg="#E8F5E9")
tk.Label(frame, text="⚙️ 设置页面", font=("Arial", 18), bg="#E8F5E9").pack(pady=50)
tk.Label(frame, text="这是系统设置模块", bg="#E8F5E9").pack()
return frame
def create_page3(self):
frame = tk.Frame(self.container, bg="#FFF3E0")
tk.Label(frame, text="ℹ️ 关于页面", font=("Arial", 18), bg="#FFF3E0").pack(pady=50)
tk.Label(frame, text="版本: 1.0.0", bg="#FFF3E0").pack()
return frame
def create_nav(self):
nav_frame = tk.Frame(self.master)
nav_frame.pack(side=tk.BOTTOM, pady=10)
tk.Button(nav_frame, text="数据", command=lambda: self.show_page(self.page1)).pack(side=tk.LEFT, padx=5)
tk.Button(nav_frame, text="设置", command=lambda: self.show_page(self.page2)).pack(side=tk.LEFT, padx=5)
tk.Button(nav_frame, text="关于", command=lambda: self.show_page(self.page3)).pack(side=tk.LEFT, padx=5)
def show_page(self, page):
# 隐藏所有页面
self.page1.pack_forget()
self.page2.pack_forget()
self.page3.pack_forget()
# 显示指定页面
page.pack(fill=tk.BOTH, expand=True)
# 使用
root = tk.Tk()
app = MultiPageApp(root)
root.mainloop()
11. 样式与主题
11.1 使用ttk主题
import tkinter as tk
from tkinter import ttk
window = tk.Tk()
window.title("ttk主题演示")
window.geometry("400x400")
# 查看可用主题
themes = ttk.Style().theme_names()
print("可用主题:", themes)
# 选择主题
ttk.Style().theme_use("clam") # 可选: default, alt, clam, vista, xpnative
# 创建组件
ttk.Label(window, text="ttk标签", font=("Arial", 12)).pack(pady=10)
ttk.Button(window, text="ttk按钮").pack(pady=5)
ttk.Entry(window, width=20).pack(pady=5)
ttk.Combobox(window, values=["选项1", "选项2"], width=18).pack(pady=5)
# 创建Frame
frame = ttk.LabelFrame(window, text="分组", padding=10)
frame.pack(pady=15, padx=10, fill=tk.X)
ttk.Label(frame, text="在Frame内的标签").pack()
ttk.Button(frame, text="在Frame内的按钮").pack(pady=5)
# 创建进度条
ttk.Label(window, text="进度条:").pack()
progress = ttk.Progressbar(window, mode="indeterminate", length=200)
progress.pack(pady=5)
progress.start()
# 样式自定义
style = ttk.Style()
style.configure("Custom.TButton", font=("Arial", 10, "bold"))
ttk.Button(window, text="自定义样式按钮", style="Custom.TButton").pack(pady=15)
window.mainloop()
11.2 常用样式配置
import tkinter as tk
from tkinter import ttk
style = ttk.Style()
# 配置按钮样式
style.configure(
"TButton",
padding=6,
relief="flat",
background="#4CAF50",
font=("Arial", 10)
)
# 配置标签样式
style.configure(
"TLabel",
font=("Arial", 11),
foreground="#333333"
)
# 配置Frame样式
style.configure(
"TFrame",
background="#f5f5f5"
)
# 配置LabelFrame样式
style.configure(
"TLabelframe",
background="#ffffff",
relief="solid"
)
# 配置Treeview样式
style.configure(
"Treeview",
background="#ffffff",
foreground="#333333",
fieldbackground="#ffffff"
)
style.map(
"Treeview",
background=[("selected", "#4CAF50")],
foreground=[("selected", "#ffffff")]
)
12. 实战项目
12.1 项目一:简易计算器
import tkinter as tk
class Calculator:
def __init__(self, master):
self.master = master
self.master.title("简易计算器")
self.master.geometry("300x400")
self.current = ""
self.create_widgets()
def create_widgets(self):
# 显示框
self.display = tk.Entry(
self.master,
font=("Arial", 24),
bd=10,
insertwidth=2,
width=12,
justify="right"
)
self.display.grid(row=0, column=0, columnspan=4, sticky="nsew")
# 按钮布局
buttons = [
("C", 1, 0), ("(", 1, 1), (")", 1, 2), ("÷", 1, 3),
("7", 2, 0), ("8", 2, 1), ("9", 2, 2), ("×", 2, 3),
("4", 3, 0), ("5", 3, 1), ("6", 3, 2), ("-", 3, 3),
("1", 4, 0), ("2", 4, 1), ("3", 4, 2), ("+", 4, 3),
("0", 5, 0), (".", 5, 1), ("⌫", 5, 2), ("=", 5, 3),
]
for (text, row, col) in buttons:
self.create_button(text, row, col)
def create_button(self, text, row, col):
if text == "=":
cmd = self.calculate
bg = "#4CAF50"
elif text == "C":
cmd = self.clear
bg = "#f44336"
elif text == "⌫":
cmd = self.backspace
bg = "#FF9800"
elif text in "+-×÷":
cmd = lambda t=text: self.click_operator(t)
bg = "#607D8B"
else:
cmd = lambda t=text: self.click_number(t)
bg = "#E0E0E0"
btn = tk.Button(
self.master,
text=text,
font=("Arial", 18),
bg=bg,
fg="white" if text in "=C⌫+-×÷" else "black",
bd=3,
command=cmd
)
btn.grid(row=row, column=col, sticky="nsew", padx=2, pady=2)
def click_number(self, num):
self.current += num
self.display.delete(0, tk.END)
self.display.insert(0, self.current)
def click_operator(self, op):
if self.current and self.current[-1] not in "+-×÷":
self.current += op
self.display.delete(0, tk.END)
self.display.insert(0, self.current)
def calculate(self):
try:
expr = self.current.replace("×", "*").replace("÷", "/")
result = eval(expr)
self.display.delete(0, tk.END)
self.display.insert(0, str(result))
self.current = str(result)
except:
self.display.delete(0, tk.END)
self.display.insert(0, "错误")
self.current = ""
def clear(self):
self.current = ""
self.display.delete(0, tk.END)
def backspace(self):
self.current = self.current[:-1]
self.display.delete(0, tk.END)
self.display.insert(0, self.current)
# 运行
root = tk.Tk()
app = Calculator(root)
root.mainloop()
运行效果:
![图片[15]-Python 进阶教程:Tkinter GUI 图形界面编程-小程博客](https://www.zenly.ink/wp-content/uploads/2026/05/86e74ba54b20260515105534.png)
上图展示了使用Tkinter实现的简易计算器界面,包含数字按钮、运算符和显示区域。
12.2 项目二:待办事项应用
import tkinter as tk
from tkinter import messagebox
import json
class TodoApp:
def __init__(self, master):
self.master = master
self.master.title("待办事项")
self.master.geometry("400x500")
self.todos = []
self.load_todos()
self.create_widgets()
self.update_list()
def create_widgets(self):
# 标题
tk.Label(
self.master,
text="📝 待办事项",
font=("Arial", 20, "bold")
).pack(pady=10)
# 输入框
input_frame = tk.Frame(self.master)
input_frame.pack(pady=10, padx=10, fill=tk.X)
self.entry = tk.Entry(input_frame, font=("Arial", 12))
self.entry.pack(side=tk.LEFT, fill=tk.X, expand=True, padx=(0, 10))
tk.Button(
input_frame,
text="添加",
command=self.add_todo,
bg="#4CAF50",
fg="white",
width=8
).pack(side=tk.LEFT)
# 列表框
self.listbox = tk.Listbox(
self.master,
font=("Arial", 12),
height=15,
selectmode=tk.SINGLE
)
self.listbox.pack(pady=10, padx=10, fill=tk.BOTH, expand=True)
# 按钮栏
btn_frame = tk.Frame(self.master)
btn_frame.pack(pady=10)
tk.Button(
btn_frame,
text="✓ 完成",
command=self.complete_todo,
width=10
).pack(side=tk.LEFT, padx=5)
tk.Button(
btn_frame,
text="✗ 删除",
command=self.delete_todo,
width=10
).pack(side=tk.LEFT, padx=5)
tk.Button(
btn_frame,
text="💾 保存",
command=self.save_todos,
width=10,
bg="#2196F3",
fg="white"
).pack(side=tk.LEFT, padx=5)
def add_todo(self):
text = self.entry.get().strip()
if text:
self.todos.append({"text": text, "done": False})
self.entry.delete(0, tk.END)
self.update_list()
def complete_todo(self):
try:
idx = self.listbox.curselection()[0]
self.todos[idx]["done"] = not self.todos[idx]["done"]
self.update_list()
except:
messagebox.showwarning("提示", "请先选择一个事项")
def delete_todo(self):
try:
idx = self.listbox.curselection()[0]
del self.todos[idx]
self.update_list()
except:
messagebox.showwarning("提示", "请先选择一个事项")
def update_list(self):
self.listbox.delete(0, tk.END)
for todo in self.todos:
prefix = "✓" if todo["done"] else "○"
text = f"{prefix} {todo['text']}"
if todo["done"]:
text = f"✓ {todo['text']} (已完成)"
self.listbox.insert(tk.END, text)
def save_todos(self):
with open("todos.json", "w", encoding="utf-8") as f:
json.dump(self.todos, f, ensure_ascii=False)
messagebox.showinfo("保存", "待办事项已保存!")
def load_todos(self):
try:
with open("todos.json", "r", encoding="utf-8") as f:
self.todos = json.load(f)
except:
self.todos = []
# 运行
root = tk.Tk()
app = TodoApp(root)
root.mainloop()
运行效果:
![图片[16]-Python 进阶教程:Tkinter GUI 图形界面编程-小程博客](https://www.zenly.ink/wp-content/uploads/2026/05/f7a631236920260515105547.png)
上图展示了待办事项应用界面,支持添加、完成和删除任务。
12.3 项目三:图片查看器
import tkinter as tk
from tkinter import filedialog, messagebox
from PIL import Image, ImageTk
class ImageViewer:
def __init__(self, master):
self.master = master
self.master.title("图片查看器")
self.master.geometry("600x500")
self.image = None
self.photo = None
self.create_widgets()
def create_widgets(self):
# 工具栏
toolbar = tk.Frame(self.master)
toolbar.pack(side=tk.TOP, fill=tk.X, padx=5, pady=5)
tk.Button(toolbar, text="📂 打开", command=self.open_image).pack(side=tk.LEFT, padx=5)
tk.Button(toolbar, text="🔄 缩放", command=self.reset_zoom).pack(side=tk.LEFT, padx=5)
tk.Button(toolbar, text="➕ 放大", command=self.zoom_in).pack(side=tk.LEFT, padx=5)
tk.Button(toolbar, text="➖ 缩小", command=self.zoom_out).pack(side=tk.LEFT, padx=5)
# 画布
self.canvas = tk.Canvas(self.master, bg="#333333")
self.canvas.pack(fill=tk.BOTH, expand=True)
# 状态栏
self.status = tk.Label(self.master, text="请打开图片", relief=tk.SUNKEN)
self.status.pack(side=tk.BOTTOM, fill=tk.X)
# 绑定鼠标滚轮缩放
self.canvas.bind("<MouseWheel>", self.on_mouse_wheel)
def open_image(self):
filename = filedialog.askopenfilename(
title="选择图片",
filetypes=[
("图片文件", "*.png *.jpg *.jpeg *.gif *.bmp"),
("所有文件", "*.*")
]
)
if filename:
try:
self.image = Image.open(filename)
self.filename = filename
self.scale = 1.0
self.show_image()
self.status.config(text=f"已打开: {filename}")
except Exception as e:
messagebox.showerror("错误", f"无法打开图片:\n{e}")
def show_image(self):
if self.image:
# 计算缩放后的尺寸
w, h = self.image.size
new_w = int(w * self.scale)
new_h = int(h * self.scale)
# 缩放图片
display_image = self.image.resize((new_w, new_h), Image.Resampling.LANCZOS)
self.photo = ImageTk.PhotoImage(display_image)
# 清空画布并显示图片
self.canvas.delete("all")
self.canvas.create_image(new_w//2, new_h//2, image=self.photo)
# 更新状态
self.status.config(
text=f"尺寸: {w}x{h} | 缩放: {int(self.scale*100)}%"
)
def zoom_in(self):
self.scale *= 1.2
self.show_image()
def zoom_out(self):
self.scale /= 1.2
self.show_image()
def reset_zoom(self):
self.scale = 1.0
self.show_image()
def on_mouse_wheel(self, event):
if event.delta > 0:
self.zoom_in()
else:
self.zoom_out()
# 运行
root = tk.Tk()
app = ImageViewer(root)
root.mainloop()
13. 常见问题与解决方案
13.1 问题排查表
| 问题 | 原因 | 解决方案 |
|---|---|---|
| 窗口不显示 | 没有调用mainloop() | 添加window.mainloop() |
| 组件不显示 | 没有调用pack/grid/place | 添加布局管理器方法 |
| 输入框无法输入 | Entry组件被禁用 | 设置state=tk.NORMAL |
| 按钮command不响应 | 函数调用写法错误 | command=self.func不带括号 |
| 中文显示乱码 | 字体不支持中文 | 使用支持中文的字体如”微软雅黑” |
| 图片不显示 | 路径错误或格式不支持 | 检查路径,使用PIL加载图片 |
| 窗口闪退 | 程序执行完自动退出 | 在末尾调用mainloop() |
| Listbox选不中 | Selection事件绑定错误 | 使用<<ListboxSelect>>事件 |
13.2 常见错误代码
# ❌ 错误:command写成函数调用
button = tk.Button(text="点击", command=on_click()) # 会立即执行
# ✅ 正确:command写成函数引用
button = tk.Button(text="点击", command=on_click)
# ❌ 错误:忘记pack
label = tk.Label(text="Hello")
# 没有调用pack(),组件不会显示
# ✅ 正确:调用pack
label.pack()
# ❌ 错误:在循环中创建多个mainloop
for i in range(5):
root = tk.Tk()
root.mainloop() # 错误做法
# ✅ 正确:只创建一个主窗口
root = tk.Tk()
# ... 添加所有组件
root.mainloop()
# ❌ 错误:忘记self导致变量作用域问题
def create_widgets(self):
label = tk.Label(...) # 错误:应该是self.label
label.pack()
14. 最佳实践
14.1 代码组织结构
import tkinter as tk
from tkinter import ttk, messagebox, filedialog
class Application(tk.Tk):
"""应用程序主类"""
def __init__(self):
super().__init__()
self.title("我的应用")
self.geometry("800x600")
self.create_widgets()
self.create_menu()
self.create_layout()
def create_widgets(self):
"""创建所有组件"""
pass
def create_menu(self):
"""创建菜单"""
pass
def create_layout(self):
"""设置布局"""
pass
def on_open(self):
"""打开文件"""
pass
def on_save(self):
"""保存文件"""
pass
if __name__ == "__main__":
app = Application()
app.mainloop()
14.2 性能优化建议
| 优化项 | 方法 | 效果 |
|---|---|---|
| 减少组件创建 | 复用组件而非重建 | 提升响应速度 |
| 使用ttk组件 | 替换tk组件为ttk | 更美观、性能更好 |
| 延迟更新 | 使用after()批量更新 | 减少卡顿 |
| 图片缓存 | 预加载并缓存图片 | 加快显示 |
| 批量绑定 | 同一事件类型绑定到容器 | 简化代码 |
14.3 安全注意事项
# 1. 输入验证
def validate_input(text):
if not text.isdigit():
return False
value = int(text)
return 0 <= value <= 100
# 2. 防止SQL注入(如果涉及数据库)
def safe_query(user_input):
# 使用参数化查询
cursor.execute("SELECT * FROM users WHERE name = ?", (user_input,))
# 3. 文件路径安全
def safe_open_file(filepath):
import os
real_path = os.path.realpath(filepath)
if not real_path.startswith(ALLOWED_DIR):
return None
return open(real_path, 'r')
附录
A. 快捷键参考
| 快捷键 | 功能 | 适用场景 |
|---|---|---|
Ctrl+N | 新建 | 文件操作 |
Ctrl+O | 打开 | 文件操作 |
Ctrl+S | 保存 | 文件操作 |
Ctrl+Z | 撤销 | 文本编辑 |
Ctrl+C | 复制 | 通用 |
Ctrl+V | 粘贴 | 通用 |
Escape | 取消/关闭 | 通用 |
B. 颜色代码速查
| 颜色名 | 十六进制 | 效果 |
|---|---|---|
| 红色 | #FF6B6B | 🔴 |
| 蓝色 | #4ECDC4 | 🔵 |
| 绿色 | #45B7D1 | 🟢 |
| 黄色 | #FFEAA7 | 🟡 |
| 紫色 | #A29BFE | 🟣 |
| 橙色 | #FDCB6E | 🟠 |
| 灰色 | #636E72 | ⚫ |
参考资料
- Python官方Tkinter文档
- Real Python Tkinter教程
- Tkinter Tutorial – pythontutorial.net
- GeeksforGeeks Tkinter教程
📝 文档版本: 1.0 🔧 最后更新: 2024年 💡 提示: 建议配合Python IDLE或IDE实际运行代码进行学习!













暂无评论内容