Python Tkinter 完整指南
Tkinter 是 Python 的标准 GUI(图形用户界面)库,它是一个轻量级的、跨平台的工具包,使用 Tk 的图形库,由于它是 Python 的内置库,所以无需额外安装,非常适合快速创建简单的桌面应用程序。

目录
- 核心概念
- 什么是 Tkinter?
- Tkinter 的核心组件
- 一个简单的 Tkinter 应用程序
- 常用控件
- 窗口
- 按钮
- 输入框
- 文本框
- 单选按钮
- 复选框
- 框架
- 菜单栏
- 消息框
- 布局管理
pack():简单打包grid():网格布局place():精确放置
- 事件处理
- 绑定事件
- 获取事件信息
- 高级主题
- 使用
ttk控件(现代外观) - 对话框
- Canvas 画布
- 线程与 Tkinter
- 使用
- 完整示例
一个简单的计算器应用
- 资源与学习
核心概念
1 什么是 Tkinter?
Tkinter 是一个 Python 的“绑定”,它将 Tcl/Tk 工具包的强大功能与 Python 的简洁语法连接起来,通过 Tkinter,你可以创建窗口、按钮、文本框等 GUI 元素,并将它们组织成功能齐全的应用程序。
2 Tkinter 的核心组件
- Tk: 这是主窗口或根窗口,所有其他 GUI 控件(称为 "widgets")都必须被放置在一个 Tk 窗口内,它是应用程序的起点。
- Widget (控件): GUI 的基本构建块,如按钮、标签、输入框等。
- Geometry Manager (几何管理器): 负责将控件放置在窗口中的方法,主要有三种:
pack,grid, 和place。
3 一个简单的 Tkinter 应用程序
这是你的第一个 Tkinter 程序,它创建一个窗口,上面有一个标签和一个按钮。
import tkinter as tk
from tkinter import ttk
# 1. 创建主窗口
root = tk.Tk()"我的第一个 Tkinter 窗口")
root.geometry("300x200") # 设置窗口大小 (宽x高)
# 2. 创建一个标签
label = ttk.Label(root, text="你好, Tkinter!")
label.pack(pady=10) # 使用 pack 布局,并添加上下边距
# 3. 创建一个按钮
def on_button_click():
label.config(text="按钮被点击了!")
button = ttk.Button(root, text="点击我", command=on_button_click)
button.pack(pady=10)
# 4. 启动主事件循环
root.mainloop()
代码解释:

import tkinter as tk: 导入 Tkinter 库,通常简写为tk。from tkinter import ttk: 导入ttk模块,它提供了更现代的控件主题。root = tk.Tk(): 创建一个主窗口对象。root.title(...): 设置窗口的标题。root.geometry(...): 设置窗口的初始大小。ttk.Label(...): 创建一个标签控件。root是它的父容器。label.pack(...): 使用pack函数将标签放入窗口。pady=10在垂直方向上添加了 10 像素的边距。ttk.Button(...): 创建一个按钮。command=on_button_click指定了点击按钮时要执行的函数。root.mainloop(): 这是最重要的部分,它启动一个事件循环,让窗口保持显示并响应用户操作(如点击、移动鼠标等),没有它,窗口会一闪而过。
常用控件
1 窗口
tk.Tk() 创建主窗口,你也可以使用 tk.Toplevel() 创建额外的顶级窗口(类似于对话框)。
import tkinter as tk
root = tk.Tk()"主窗口")
root.geometry("300x200")
# 创建一个子窗口
top = tk.Toplevel(root)"子窗口")
top.geometry("200x150")
root.mainloop()
2 标签
用于显示单行文本或图像。
label = ttk.Label(root, text="这是一个标签", font=("Arial", 12, "bold"))
label.pack()
3 按钮
用于触发一个动作。
def say_hello():
print("Hello from button!")
button = ttk.Button(root, text="说你好", command=say_hello)
button.pack()
4 输入框
用于单行文本输入。

entry = ttk.Entry(root)
entry.pack(pady=5)
def show_entry_content():
content = entry.get() # 获取输入框的内容
print(f"输入的内容是: {content}")
show_button = ttk.Button(root, text="显示内容", command=show_entry_content)
show_button.pack()
5 文本框
用于多行文本输入或显示。
text = tk.Text(root, height=10, width=40)
text.pack(pady=10)
# 插入文本
text.insert(tk.END, "这是文本框的第一行,\n")
text.insert(tk.END, "这是第二行。")
# 获取文本
def get_text_content():
content = text.get("1.0", tk.END) # "1.0" 表示第一行第一列
print(f"文本框内容:\n{content}")
get_button = ttk.Button(root, text="获取文本", command=get_text_content)
get_button.pack()
6 单选按钮
用于从一组选项中选择一个。
selected_var = tk.StringVar() # 使用 StringVar 来跟踪选中的值
def update_selection():
print(f"选中了: {selected_var.get()}")
# 创建一组单选按钮
ttk.Radiobutton(root, text="选项 A", variable=selected_var, value="A").pack()
ttk.Radiobutton(root, text="选项 B", variable=selected_var, value="B").pack()
ttk.Radiobutton(root, text="选项 C", variable=selected_var, value="C").pack()
update_button = ttk.Button(root, text="确认选择", command=update_selection)
update_button.pack()
7 复选框
用于选择或取消选择一个选项。
# 使用 IntVar 来跟踪复选框状态 (0=未选中, 1=选中)
var1 = tk.IntVar()
var2 = tk.IntVar()
cb1 = ttk.Checkbutton(root, text="选项 1", variable=var1)
cb2 = ttk.Checkbutton(root, text="选项 2", variable=var2)
cb1.pack()
cb2.pack()
def check_status():
print(f"选项1状态: {var1.get()}")
print(f"选项2状态: {var2.get()}")
check_button = ttk.Button(root, text="检查状态", command=check_status)
check_button.pack()
8 框架
一个容器控件,用于将其他控件分组。
frame = ttk.Frame(root, borderwidth=2, relief="groove") frame.pack(pady=10, padx=10, fill="x") # fill="x" 使框架水平拉伸 label_in_frame = ttk.Label(frame, text="我在框架里") label_in_frame.pack(side="left", padx=5, pady=5) button_in_frame = ttk.Button(frame, text="我也是") button_in_frame.pack(side="left", padx=5, pady=5)
9 菜单栏
menubar = tk.Menu(root)
# 创建 "文件" 菜单
file_menu = tk.Menu(menubar, tearoff=0)
file_menu.add_command(label="新建", command=lambda: print("新建文件"))
file_menu.add_command(label="打开", command=lambda: print("打开文件"))
file_menu.add_separator()
file_menu.add_command(label="退出", command=root.quit)
menubar.add_cascade(label="文件", menu=file_menu)
# 创建 "编辑" 菜单
edit_menu = tk.Menu(menubar, tearoff=0)
edit_menu.add_command(label="撤销", command=lambda: print("撤销"))
edit_menu.add_command(label="重做", command=lambda: print("重做"))
menubar.add_cascade(label="编辑", menu=edit_menu)
root.config(menu=menubar)
10 消息框
用于显示信息、警告或询问问题。
from tkinter import messagebox
def show_info():
messagebox.showinfo("信息", "这是一个信息框")
def show_warning():
messagebox.showwarning("警告", "这是一个警告框!")
def show_error():
messagebox.showerror("错误", "发生了一个错误!")
def ask_question():
answer = messagebox.askquestion("问题", "你确定要继续吗?")
if answer == 'yes':
print("用户选择了 '是'")
else:
print("用户选择了 '否'")
btn_info = ttk.Button(root, text="显示信息", command=show_info)
btn_info.pack(pady=5)
btn_warning = ttk.Button(root, text="显示警告", command=show_warning)
btn_warning.pack(pady=5)
btn_error = ttk.Button(root, text="显示错误", command=show_error)
btn_error.pack(pady=5)
btn_question = ttk.Button(root, text="询问问题", command=ask_question)
btn_question.pack(pady=5)
布局管理
布局管理器决定了控件在窗口中的位置和大小。
1 pack() - 简单打包
pack() 是最简单的布局方式,它按照添加的顺序将控件堆叠起来。
side: 控件在哪一边("top","bottom","left","right")。fill: 是否填充可用空间("x","y","both")。expand: 是否扩展以填充父容器(True/False)。padx/pady: 外部边距。
b1 = ttk.Button(root, text="按钮 1") b1.pack(side="top", fill="x") b2 = ttk.Button(root, text="按钮 2") b2.pack(side="top", fill="x") b3 = ttk.Button(root, text="按钮 3") b3.pack(side="left", fill="y", expand=True)
2 grid() - 网格布局
grid() 将父容器划分为一个网格,通过行和列来放置控件,这是最常用和最灵活的布局方式。
row: 行号 (从 0 开始)。column: 列号 (从 0 开始)。rowspan: 跨越的行数。columnspan: 跨越的列数。sticky: 如何对齐控件("n","s","e","w"或它们的组合,如"ew"表示水平拉伸)。
# 创建一个登录表单 ttk.Label(root, text="用户名:").grid(row=0, column=0, padx=5, pady=5, sticky="w") ttk.Entry(root).grid(row=0, column=1, padx=5, pady=5, sticky="ew") ttk.Label(root, text="密码:").grid(row=1, column=0, padx=5, pady=5, sticky="w") ttk.Entry(root, show="*").grid(row=1, column=1, padx=5, pady=5, sticky="ew") login_button = ttk.Button(root, text="登录") login_button.grid(row=2, column=0, columnspan=2, pady=10) # 让第1列可以水平拉伸 root.grid_columnconfigure(1, weight=1)
3 place() - 精确放置
place() 允许你通过精确的坐标(x, y)来放置控件,它不常用,因为它使界面难以适应不同大小的窗口。
x: x 坐标。y: y 坐标。relx: 相对 x 位置 (0.0 到 1.0)。rely: 相对 y 位置 (0.0 到 1.0)。anchor: 锚点("nw","center","se"等)。
b1 = ttk.Button(root, text="精确放置") b1.place(x=50, y=50) # 在 (50, 50) 坐标放置
事件处理
Tkinter 应用程序是事件驱动的,事件包括鼠标点击、键盘按键、窗口关闭等。
1 绑定事件
使用 bind() 方法将一个事件与一个回调函数关联起来。
def on_key_press(event):
# event.keysym 获取按下的键的符号
print(f"你按下了: {event.keysym}")
def on_mouse_click(event):
# event.x, event.y 获取鼠标点击的坐标
print(f"鼠标在 ({event.x}, {event.y}) 处被点击")
# 绑定键盘事件到整个窗口
root.bind("<KeyPress>", on_key_press)
# 绑定鼠标左键点击事件到标签
label.bind("<Button-1>", on_mouse_click)
常见事件类型:
<Button-1>: 鼠标左键点击<Button-3>: 鼠标右键点击<Double-Button-1>: 鼠标左键双击<KeyPress>: 任意键按下<Key-a>: 特定键 'a' 按下<Enter>: 鼠标进入控件区域<Leave>: 鼠标离开控件区域<Configure>: 窗口大小改变
高级主题
1 使用 ttk 控件
tkinter.ttk 模块提供了主题控件,它们的外观更现代,并且会自动适应操作系统的主题。强烈建议在创建新应用时优先使用 ttk 控件。
大部分 tk 控件都有一个对应的 ttk 版本(如 tk.Label -> ttk.Label),但 ttk 不支持所有 tk 的选项(如 bg, fg),对于 ttk,通常使用 style 对象来修改外观。
import tkinter as tk
from tkinter import ttk
root = tk.Tk()
# 使用 ttk 控件
ttk.Label(root, text="TTK 标签", background="white").pack()
tk.Label(root, text="TK 标签", bg="yellow").pack() # TK 控件可以直接使用 bg
# 使用 Style 修改 ttk 控件样式
style = ttk.Style()
style.configure("TButton", font=("Helvetica", 12), padding=10)
style.map("TButton", foreground=[('pressed', 'red'), ('active', 'blue')])
ttk.Button(root, text="样式化按钮", style="TButton").pack()
root.mainloop()
2 对话框
除了 messagebox,filedialog 和 colorchooser 也非常常用。
from tkinter import filedialog, colorchooser
def open_file():
filepath = filedialog.askopenfilename(
title="选择一个文件",
filetypes=[("文本文件", "*.txt"), ("所有文件", "*.*")]
)
if filepath:
print(f"选择的文件是: {filepath}")
def choose_color():
color = colorchooser.askcolor(title="选择一个颜色")
if color[1]: # color 是一个元组 (RGB元组, 十六进制字符串)
print(f"选择的颜色是: {color[1]}")
# 可以用这个颜色来设置某个控件的背景
# root.config(bg=color[1])
btn_file = ttk.Button(root, text="打开文件", command=open_file)
btn_file.pack(pady=5)
btn_color = ttk.Button(root, text="选择颜色", command=choose_color)
btn_color.pack(pady=5)
3 Canvas 画布
Canvas 是一个功能强大的控件,用于绘制图形、线条、形状,甚至可以放置其他控件。
canvas = tk.Canvas(root, width=400, height=300, bg="white")
canvas.pack()
# 绘制一个矩形
canvas.create_rectangle(50, 50, 150, 150, fill="blue", outline="black")
# 绘制一个圆形 (oval)
canvas.create_oval(200, 50, 300, 150, fill="red", outline="black")
# 绘制一条线
canvas.create_line(10, 200, 390, 200, width=5, fill="green")
# 添加文本
canvas.create_text(200, 250, text="这是一个画布", font=("Arial", 16))
4 线程与 Tkinter
重要原则:Tkinter 的所有操作(包括更新界面)都必须在主线程中执行。 如果你有一个耗时的任务(如下载数据、进行复杂计算),它会阻塞主线程,导致界面卡死。
解决方案: 使用一个单独的线程来执行耗时任务,然后通过 queue.Queue 将结果安全地传递回主线程,再由主线程更新界面。
import threading
import queue
import time
def long_running_task(q):
for i in range(5):
time.sleep(1) # 模拟耗时操作
q.put(f"任务进度: {i+1}/5")
q.put("任务完成!")
def update_gui():
try:
message = q.get_nowait()
label.config(text=message)
except queue.Empty:
pass
# 每100毫秒检查一次队列
root.after(100, update_gui)
root = tk.Tk()"线程示例")
label = ttk.Label(root, text="等待任务开始...")
label.pack(pady=20)
button = ttk.Button(root, text="启动任务", command=lambda: threading.Thread(target=long_running_task, args=(q,), daemon=True).start())
button.pack()
# 创建一个队列
q = queue.Queue()
# 启动GUI更新循环
update_gui()
root.mainloop()
完整示例:一个简单的计算器
这个示例结合了布局、事件处理和多种控件。
import tkinter as tk
from tkinter import ttk
# --- 全局变量 ---
current_input = ""
result_var = tk.StringVar()
# --- 按钮点击处理函数 ---
def button_click(char):
global current_input
current_input += str(char)
result_var.set(current_input)
def clear():
global current_input
current_input = ""
result_var.set("")
def calculate():
global current_input
try:
# 使用 eval 计算表达式 (注意:eval 有安全风险,仅用于演示)
result = eval(current_input)
result_var.set(str(result))
current_input = str(result) # 将结果作为下一次计算的输入
except Exception as e:
result_var.set("错误")
current_input = ""
# --- 创建主窗口 ---
root = tk.Tk()"简单计算器")
root.geometry("300x400")
# --- 显示结果的标签 ---
result_display = ttk.Entry(root, textvariable=result_var, font=('Arial', 24), justify='right')
result_display.grid(row=0, column=0, columnspan=4, sticky="nsew", padx=10, pady=10)
# --- 按钮布局 ---
buttons = [
'7', '8', '9', '/',
'4', '5', '6', '*',
'1', '2', '3', '-',
'C', '0', '=', '+'
]
row_val = 1
col_val = 0
for button_text in buttons:
if button_text == '=':
btn = ttk.Button(root, text=button_text, command=calculate)
elif button_text == 'C':
btn = ttk.Button(root, text=button_text, command=clear)
else:
btn = ttk.Button(root, text=button_text, command=lambda t=button_text: button_click(t))
btn.grid(row=row_val, column=col_val, sticky="nsew", padx=5, pady=5)
col_val += 1
if col_val > 3:
col_val = 0
row_val += 1
# 配置网格权重,使按钮可以拉伸
for i in range(5):
root.grid_rowconfigure(i, weight=1)
for i in range(4):
root.grid_columnconfigure(i, weight=1)
# --- 启动主循环 ---
root.mainloop()
资源与学习
- Python 官方文档 (Tkinter 部分): https://docs.python.org/3/library/tkinter.html (最权威的资料)
- Tkinter 参考文档: https://tkdocs.com/ (非常棒的在线教程和参考,强烈推荐!)
- Effortless GUIs in Python: https://build-system.fman.io/tkinter-book/ (一本免费的在线书)
- Stack Overflow: 搜索问题时,使用
python tkinter作为关键词,可以找到大量现成的解决方案。
希望这份详细的指南能帮助你掌握 Python Tkinter!从创建简单的窗口开始,逐步尝试不同的控件和布局,你很快就能构建出自己的 GUI 应用程序。
