Python Tkinter GUI框架深度解析
什么是Tkinter
Tkinter 是 Python 的标准 GUI(图形用户界面)库。它是 Python 内置的一个模块,用于创建桌面应用程序的用户界面。Tkinter 基于 Tcl(脚本语言)/Tk(GUI工具包) 库,是 Python 提供的默认图形界面开发工具。因为它与 Python 一起分发,所以不需要单独安装,使用时只需要导入相应的模块即可。
Tkinter的跨平台性
Tkinter 可以在多个操作系统上运行,包括 Windows、macOS 和 Linux。
Python的图形用户界面
在 Python 中,有许多库可以用来创建客户端 GUI(图形用户界面)。以下是一些常见的 Python GUI 库和框架:
Tkinter:
描述: Tkinter 是 Python 的标准 GUI 库,基于 Tk GUI 工具包。 特点: 内置于 Python 标准库中,易于上手,适合快速开发简单的 GUI 应用。 PyQt:
描述: PyQt 是 Qt 库的 Python 绑定,提供了强大的跨平台 GUI 开发能力。 特点: 功能丰富,支持多种平台,适合开发复杂的应用。 PySide:
描述: PySide 是 Qt 库的另一种 Python 绑定,和 PyQt 类似,但采用了不同的许可证(LGPL)。 特点: 与 PyQt 类似,支持多平台,适合开发专业级应用。 Kivy:
描述: Kivy 是一个用于开发跨平台应用的开源 Python 库,支持触控界面。 特点: 适用于移动设备和桌面应用,支持多种输入方式。 wxPython:
描述: wxPython 是 wxWidgets C++ 库的 Python 绑定,提供了原生的 GUI 组件。 特点: 提供原生界面外观,支持多平台。 FLTK (Fast, Light Toolkit):
描述: FLTK 是一个轻量级的 C++ GUI 工具包,Python 有 FLTK 的绑定库 pyFLTK
。特点: 轻量且高效,适合对资源要求高的应用。 Dear PyGui:
描述: Dear PyGui 是一个用于创建简单而高性能 GUI 的库,特别适用于游戏和图形应用。 特点: 直观的 API 和高性能渲染。 PyGTK:
描述: PyGTK 是 GTK+ 的 Python 绑定,适用于 Linux 系统上的图形用户界面。 特点: 主要用于 Linux 系统,支持 GNOME 桌面环境。 在众多 Python GUI 库中,PyQt 和 Tkinter 是两个最为常用且功能强大的库。
Tkinter的组件
1. 顶层窗口 (Toplevel Window)
Tk: 主窗口,一个顶级窗口。 Toplevel: 创建一个子窗口,类似于 Tk 同样是个顶级窗口,但作为主窗口的子窗口存在。 2. 基本控件 (Basic Widgets)
Label: 标签,用于显示文本或图像。 Button: 按钮,用户可以点击以触发事件。 Canvas: 画布,允许绘制图形、显示图像、创建图形界面或其他小部件。 Entry: 单行文本输入框,用户可以输入文本。 Text: 多行文本框,用于显示和编辑多行文本。 Frame: 框架,用于包含其他小部件的容器。 LabelFrame: 带标题的框架,作为 Frame 的扩展。 PhotoImage: 用于显示图片(仅限 GIF 和 PGM/PPM 格式)。 3. 容器控件 (Container Widgets)
Frame: 用作其他控件的容器。 LabelFrame: 类似于 Frame,但带有标签。 PanedWindow: 可调节大小的窗口容器,包含多个子窗口。 Notebook: 选项卡式窗口容器。 4. 选择控件 (Selection Widgets)
Checkbutton: 复选按钮,用于多选。 Radiobutton: 单选按钮,用于单选。 Scale: 滑块,用于选择数值。 Spinbox: 数值选择框,允许用户选择或输入数值。 5. 菜单控件 (Menu Widgets)
Menu: 菜单栏,包含多个菜单项。 MenuButton: 菜单按钮,点击后显示下拉菜单。 6. 列表控件 (List Widgets)
Listbox: 列表框,显示一个或多个项目的列表。 Scrollbar: 滚动条,与其他控件一起使用来提供滚动功能。 7. 对话框控件 (Dialog Widgets)
Message: 信息对话框,显示多行不可编辑文本。 MessageBox: 用于显示消息对话框,如信息、警告、错误等。 FileDialog: 文件对话框,用于打开或保存文件。 ColorChooser: 颜色选择对话框,用户可以选择颜色。 SimpleDialog: 简单对话框,用于用户输入。 8. 高级控件 (Advanced Widgets)
Treeview: 树视图,用于显示分层数据。 Progressbar: 进度条,显示任务的进度。 Combobox: 组合框,类似于下拉列表。 9. 定制与布局控件 (Customization and Layout Widgets)
Place: 绝对定位管理器,允许精确控制组件位置。 Pack: 包装定位管理器,按顺序排列组件。 Grid: 网格定位管理器,在表格中排列组件。
颜色选项
标准颜色名称:如 "red"
、"blue"
、"green"
、"yellow"
等。十六进制颜色代码:如 "#FF5733"
(橙红色)、"#4CAF50"
(绿色)。RGB 颜色代码:格式为 "#RRGGBB"
,其中RR
、GG
和BB
是红色、绿色、蓝色的分量(例如"#0000FF"
表示蓝色)。
事件绑定选项
"<Button-1>"
鼠标左键点击"<Button-2>"
: 鼠标中键点击"<Button-3>"
: 鼠标右键点击"<Double-1>"
: 鼠标左键双击"<Enter>"
: 鼠标光标进入组件"<Leave>"
: 鼠标光标离开组件"<Configure>"
: 窗口或组件大小发生变法时触发"<KeyRelease>"
: 键盘随便一个按键松开时触发"<Control-z>"
: 按下Ctrl+z事件
布局管理器
pack()
相对布局管理器
pack
布局管理器按顺序将小部件放入父容器中,通常是垂直或水平的。参数详细说明:
side: 指定小部件在父容器中的哪一侧放置。可以是以下值:
TOP
: 放置在顶部(默认值)BOTTOM
: 放置在底部LEFT
: 放置在左侧RIGHT
: 放置在右侧anchor:指定组件在其可用空间内的对齐方式。该属性在组件没有完全填满其分配的空间时生效 取值:'n'、'ne'、'e'、'se'、's'、'sw'、'w'、'nw'、'center'(默认值为'center')。 ┌─────────────────────┐ │ n │ │ nw ne │ │ w center e │ │ sw se │ │ s │ └─────────────────────┘
fill: 指定小部件如何填充其父容器的空间。可以是以下值:
NONE
: 不填充(默认值)X
: 仅在水平方向填充Y
: 仅在垂直方向填充BOTH
: 在水平方向和垂直方向都填充expand: 一个布尔值,指定小部件是否应在父容器中扩展以填补额外的空间。
True
使小部件扩展,False
不扩展(默认值)。padx 和 pady: 控制小部件与父容器边界之间的水平和垂直间距。可以是单个值或两个值(分别用于 x 和 y 方向)。
ipadx 和 ipady:设置组件的内部填充(padding),即组件内容与边框之间的间距。ipadx用于水平内边距,ipady用于垂直内边距,默认值为0。
grid()
网格布局管理器
grid
布局管理器通过网格系统在父容器中定位小部件。参数详细说明:
row: 指定小部件所在的行(从 0 开始)。
column: 指定小部件所在的列(从 0 开始)。
rowspan: 指定小部件跨越的行数。
columnspan: 指定小部件跨越的列数。
sticky: 指定小部件在单元格中的对齐方式。可以是以下值:
N
: 顶部对齐S
: 底部对齐E
: 右侧对齐W
: 左侧对齐NS
: 垂直方向对齐EW
: 水平方向对齐NEWS
: 四个方向都对齐padx 和 pady: 控制小部件与单元格边界之间的水平和垂直间距。
ipadx 和 ipady: 控制小部件的内部填充,即小部件内部内容与小部件边界之间的水平和垂直间距。
place()
绝对布局管理器
place
布局管理器使用绝对定位或相对定位将小部件放置在其父容器中。参数详细说明:
x 和 y: 指定小部件的绝对坐标位置(相对于父容器的左上角)。
relx 和 rely: 指定小部件的相对坐标位置(0 到 1 之间的值,表示父容器的相对位置)。
anchor: 指定小部件在位置坐标处的对齐方式。可以是以下值之一:
N
,E
,S
,W
等,表示方位的缩写(北、东、南、西)bordermode: 指定小部件的边界模式,控制小部件位置计算是否考虑边框。可以是以下值:
INSIDE
: 位置计算不包括边框OUTSIDE
: 位置计算包括边框width 和 height: 指定小部件的宽度和高度。
relwidth 和 relheight: 指定小部件的相对宽度和高度(0 到 1 之间的值,表示父容器的相对大小)。
组件的使用
Tk主窗口组件
Tk
是创建应用程序主窗口的顶层容器。
Tk组件常用方法
1. 窗口管理方法
withdraw()
: 隐藏窗口,但不销毁它。deiconify()
: 显示一个已被withdraw()
方法隐藏的窗口。iconify()
: 最小化窗口。state()
: 返回窗口的状态(如'normal'
、'iconic'
、'withdrawn'
等)。wm_state(state=None)
:state()
方法的别名,也可以用来设置窗口状态。2. 尺寸和位置方法
geometry(newGeometry=None)
: 获取或设置窗口的大小和位置(例如"200x100+10+20"
)。maxsize(width=None, height=None)
: 获取或设置窗口的最大尺寸。minsize(width=None, height=None)
: 获取或设置窗口的最小尺寸。resizable(width=None, height=None)
: 获取或设置窗口的大小是否可变(水平和垂直方向)。positionfrom(who=None)
: 设置窗口位置的参考点。sizefrom(who=None)
: 设置窗口大小的参考来源。3. 标题和图标方法
title(string=None)
: 获取或设置窗口的标题。iconbitmap(bitmap=None)
: 设置窗口的图标。iconphoto(default=False, *args)
: 设置窗口的图标照片。4. 透明度和样式方法
attributes(*args)
: 获取或设置窗口的多种属性(如透明度、是否置顶等)。wm_attributes(*args)
: 与attributes()
方法相同,用于管理窗口属性。transient(master=None)
: 将窗口设置为临时窗口,使其在另一个窗口的上方。5. 事件处理方法
bind(sequence=None, func=None, add=None)
: 绑定事件处理程序。unbind(sequence, funcid=None)
: 解除事件处理程序的绑定。bind_all(sequence=None, func=None, add=None)
: 对所有窗口控件绑定事件处理程序。bind_class(className, sequence=None, func=None, add=None)
: 对特定控件类绑定事件处理程序。event_add(virtual, *sequences)
: 添加虚拟事件。event_delete(virtual, *sequences)
: 删除虚拟事件。event_generate(sequence, **kw)
: 生成事件。event_info(virtual=None)
: 获取有关事件的信息。6. 退出和销毁方法
destroy()
: 销毁当前窗口及其当前窗口的所有子窗口。quit()
: 退出主事件循环。7. 其他常用方法
tkraise(aboveThis=None)
: 提升窗口的堆叠顺序。lift(aboveThis=None)
: 提升窗口的堆叠顺序,tkraise()
的别名。lower(belowThis=None)
: 降低窗口的堆叠顺序。
Tk示例
1. 有图标有标题的的Tk主窗口
import tkinter as tk
root = tk.Tk()
root.title("主窗口") # 设置窗口标题
root.geometry("300x200") # 设置窗口大小
# 设置图标。图片格式
icon = tk.PhotoImage(file="static/icon/a.png")
root.iconphoto(False, icon)
root.mainloop() # 进入事件循环
2. 设置主窗口在桌面居中打开
import tkinter as tk
# 窗口居中方法
def center_window(window, width, height):
# 获取屏幕宽度和高度
screen_width = window.winfo_screenwidth()
screen_height = window.winfo_screenheight()
# 计算窗口的x和y坐标,使窗口居中
x = (screen_width - width) // 2
y = (screen_height - height) // 2
# 设置窗口的大小和位置
window.geometry(f'{width}x{height}+{x}+{y}')
root = tk.Tk()
root.title("主窗口") # 设置窗口标题
# 设置窗口大小并居中显示
window_width = 300
window_height = 200
center_window(root, window_width, window_height)
root.mainloop() # 进入事件循环
3. 设置窗口透明度
import tkinter as tk
# 创建主窗口
root = tk.Tk()
root.title("透明度的窗口")
# 设置窗口大小
root.geometry("300x200")
# 设置窗口透明度(范围从 0.0 到 1.0,1.0 表示完全不透明)
root.wm_attributes('-alpha', 0.5)
# 进入主事件循环
root.mainloop()
4. 主窗口设置背景图片,图片随着窗口大小的变化动态变化
import tkinter as tk
from PIL import Image, ImageTk
def resize_image(image, size):
"""调整图片大小以适应指定的尺寸"""
return image.resize(size, Image.LANCZOS)
def update_background(event):
"""在窗口调整大小时更新背景图片"""
global background_photo
new_width = root.winfo_width()
new_height = root.winfo_height()
# 调整图片大小以填充窗口
resized_image = resize_image(background_image, (new_width, new_height))
background_photo = ImageTk.PhotoImage(resized_image)
# 更新标签显示的图片
background_label.config(image=background_photo)
# 创建主窗口
root = tk.Tk()
root.title("动态背景图片窗口")
# 设置窗口初始大小
window_width = 500
window_height = 350
root.geometry(f'{window_width}x{window_height}')
# 使用 Pillow 加载背景图片
background_image = Image.open("static/background/a.png")
# 创建初始背景图片
initial_resized_image = resize_image(background_image, (window_width, window_height))
background_photo = ImageTk.PhotoImage(initial_resized_image)
# 创建标签以显示背景图片
background_label = tk.Label(root, image=background_photo)
background_label.place(x=0, y=0, relwidth=1, relheight=1)
# 绑定窗口大小变化事件
root.bind('<Configure>', update_background)
# 进入主事件循环
root.mainloop()
5. 主窗口设置背景颜色
import tkinter as tk
root = tk.Tk()
root.title("设置主窗口背景颜色")
root.geometry("300x200")
# 设置主窗口的背景颜色
root.configure(bg="lightblue")
# root.configure(bg="#0000AF")
root.mainloop()
Button按钮组件
Button组件常用方法
创建 Button 按钮
button = tk.Button(root, text="点击我", command=on_button_click)
root
是按钮的父容器。text
设置按钮上显示的文本。command
设置按钮被点击时调用的函数,这里是on_button_click
。设置按钮的颜色
button = tk.Button(root, text="点击我", command=on_button_click, bg="blue", fg="white")
bg
是按钮的背景颜色。也可以使用十六进制#0000FF这样的fg
是按钮的文本颜色。设置按钮的字体
button = tk.Button(root, text="点击我", command=on_button_click, font=("Arial", 14, "bold"))
font
设置字体和大小加粗设置按钮的大小
button = tk.Button(root, text="点击我", command=on_button_click, width=15, height=2)
button = tk.Button(root, text="点击我", command=on_button_click, padx=20, pady=5)
width
按钮的宽height
按钮的高padx
通过修改内边距修改按钮的宽padx
通过修改内边距修改按钮的高设置按钮的状态
button = tk.Button(root, text="点击我", command=on_button_click, state=tk.DISABLED)
state
=tk.DISABLED 按钮不可点击使用图片作为按钮
img = tk.PhotoImage(file="path_to_image.png")
button = tk.Button(root, image=img, command=on_button_click)
Button按钮的布局管理器
pack() 布局管理器
pack()
布局管理器用于将控件按顺序放置在主窗口中。它的布局方式是将控件打包到容器的顶部、底部、左侧或右侧,也可以让控件在容器中居中对齐。grid() 布局管理器
grid()
布局管理器将控件放置在一个网格中,通过指定行和列的位置来安排控件。这适用于需要精确布局的情况。place 布局管理器
place()
布局管理器允许你通过指定绝对或相对位置来放置控件。这种方法提供了最大的灵活性,但需要你手动计算位置。
Button示例
1. 创建一个button有点击事件
import tkinter as tk
# 创建主窗口
root = tk.Tk()
root.title("Tkinter Button 示例")
root.geometry("300x200")
# 定义按钮点击事件的回调函数
def on_button_click():
print("按钮被点击了!")
# 创建一个按钮
button = tk.Button(root, text="点击我", command=on_button_click)
# 放置按钮到主窗口
button.pack(padx=20, pady=20)
# 运行主循环
root.mainloop()
2. pack() 布局管理器
import tkinter as tk
root = tk.Tk()
root.title("pack 布局管理器示例")
root.geometry("300x200")
# 创建按钮并使用 pack() 布局
button1 = tk.Button(root, text="按钮上")
button1.pack(side=tk.TOP, padx=10, pady=10)
button2 = tk.Button(root, text="按钮左")
button2.pack(side=tk.LEFT, padx=10, pady=10)
button3 = tk.Button(root, text="按钮右")
button3.pack(side=tk.RIGHT, padx=10, pady=10)
button4 = tk.Button(root, text="按钮下")
button4.pack(side=tk.BOTTOM, padx=10, pady=10)
root.mainloop()
3. grid() 布局管理器
import tkinter as tk
root = tk.Tk()
root.title("grid 布局管理器示例")
root.geometry("300x200")
# 创建按钮并使用 grid() 布局
button1 = tk.Button(root, text="第一行第一列")
button1.grid(row=0, column=0, padx=10, pady=10)
button2 = tk.Button(root, text="第一行第二列")
button2.grid(row=0, column=1, padx=10, pady=10)
button3 = tk.Button(root, text="第二行第一列")
button3.grid(row=1, column=0, padx=10, pady=10)
button4 = tk.Button(root, text="第二行第二列")
button4.grid(row=1, column=1, padx=10, pady=10)
root.mainloop()
4. place() 布局管理器 写xy坐标
import tkinter as tk
root = tk.Tk()
root.title("place 布局管理器示例")
root.geometry("300x200")
# 创建按钮并使用 place() 布局
button1 = tk.Button(root, text="按钮1")
button1.place(x=20, y=20)
button2 = tk.Button(root, text="按钮2")
button2.place(x=100, y=20)
button3 = tk.Button(root, text="按钮3")
button3.place(x=20, y=100)
button4 = tk.Button(root, text="按钮4")
button4.place(x=100, y=100)
root.mainloop()
5. 按钮的边框设置
tk.RAISED
:按钮看起来有一个向上凸起的效果,边框会有阴影效果,使按钮突出。tk.SUNKEN
:按钮看起来有一个向下凹陷的效果,边框有内阴影效果,使按钮看起来被压入背景中。tk.FLAT
:按钮没有边框的立体效果,边框是平的,看起来像没有边框。tk.GROOVE
:按钮的边框看起来像是有一个凹槽效果,边框看起来凹陷。tk.RIDGE
:按钮的边框看起来像是有一个凸起的脊线效果,形成一个明显的边界。
import tkinter as tk
root = tk.Tk()
root.title("Relief 示例")
root.geometry("300x350")
# 创建不同样式的按钮
button_raised = tk.Button(root, text="Raised", relief=tk.RAISED, width=15, height=2)
button_sunken = tk.Button(root, text="Sunken", relief=tk.SUNKEN, width=15, height=2)
button_flat = tk.Button(root, text="Flat", relief=tk.FLAT, width=15, height=2)
button_groove = tk.Button(root, text="Groove", relief=tk.GROOVE, width=15, height=2)
button_ridge = tk.Button(root, text="Ridge", relief=tk.RIDGE, width=15, height=2)
# 放置按钮
button_raised.pack(padx=10, pady=10)
button_sunken.pack(padx=10, pady=10)
button_flat.pack(padx=10, pady=10)
button_groove.pack(padx=10, pady=10)
button_ridge.pack(padx=10, pady=10)
root.mainloop()
6. 按钮悬停改变颜色
import tkinter as tk
def on_enter(event):
button.config(bg="#FF0000", text="悬停中") # 悬停时修改背景颜色和文本
def on_leave(event):
button.config(bg="#71B960", text="未悬停") # 悬停时恢复背景颜色和文本
root = tk.Tk()
root.title("按钮悬停效果示例")
root.geometry("300x200")
# 创建一个按钮
button = tk.Button(
root,
text="未悬停",
bg="#71B960",
fg="white",
padx=20,
pady=5
)
# 绑定悬停事件
button.bind("<Enter>", on_enter)
button.bind("<Leave>", on_leave)
button.pack(padx=20, pady=20)
root.mainloop()
7. 图片当作按钮
import tkinter as tk
from PIL import Image, ImageTk
def create_resized_image(image_path, size):
# 打开图像
image = Image.open(image_path)
# 调整图像大小
image = image.resize(size, Image.LANCZOS)
# 转换为 PhotoImage 对象
return ImageTk.PhotoImage(image)
root = tk.Tk()
root.title("调整图像大小的按钮示例")
root.geometry("300x200") # 窗口的大小
# 设置按钮大小
button_size = (120, 60) # 例如:宽度 120 像素,高度 60 像素
# 载入并调整图像大小
photo = create_resized_image("static/icon/b.png", button_size) # 替换为你的图像路径
# 创建一个按钮并设置图像
button = tk.Button(
root,
text="图像按钮", # 文本内容
compound=tk.CENTER, # 图像和文本的组合方式
fg="white", # 文本颜色
image=photo, # 图片
borderwidth=0, # 去除按钮边框, 点击时看不到边框
relief=tk.FLAT, # 边框是平的,看起来像没有边框
)
button.pack(padx=20, pady=20)
root.mainloop()
Toplevel子窗口组件
Toplevel组件常用方法
title():设置或获取窗口的标题。 geometry():设置或获取窗口的尺寸和位置。 resizable():设置窗口是否可以调整大小。 configure():配置窗口的各种选项,如背景色、字体等。 transient():将窗口标记为某个窗口的临时窗口,通常用于对话框。 grab_set():捕获所有的用户输入,直到窗口被销毁或调用 grab_release()。 wait_window():阻塞主循环,直到窗口被销毁。 destroy():销毁窗口,关闭窗口并释放资源。 withdraw():隐藏窗口而不是销毁它,可以稍后使用 deiconify() 恢复显示。 iconbitmap():设置窗口的图标。 protocol():设置窗口关闭时的处理方法,例如添加自定义的处理函数。 focus_set():设置窗口为当前活动窗口,使其获得焦点。
Toplevel组件示例
1. 打开一个子窗口
import tkinter as tk
def open_new_window():
# 创建新的 Toplevel 窗口
new_window = tk.Toplevel(root)
new_window.title("子窗口")
new_window.geometry("250x150")
# 在新窗口中添加一些控件
label = tk.Label(new_window, text="这是一个子窗口")
label.pack(padx=20, pady=20)
button = tk.Button(new_window, text="Close", command=new_window.destroy)
button.pack(pady=10)
# 创建主窗口
root = tk.Tk()
root.title("主窗口")
root.geometry("300x200")
# 在主窗口中添加一个按钮,点击后打开新的 Toplevel 窗口
open_button = tk.Button(root, text="打开子窗口", command=open_new_window)
open_button.pack(padx=20, pady=20)
# 运行应用程序
root.mainloop()
2. 打开一个子窗口,传递参数到子窗口
import tkinter as tk
def open_new_window(param1, param2):
# 创建新的 Toplevel 窗口
new_window = tk.Toplevel(root)
new_window.title("子窗口")
new_window.geometry("250x150")
# 在新窗口中添加一些控件
label = tk.Label(new_window, text="这是一个子窗口")
label.pack(padx=10, pady=10)
# 在 Toplevel 窗口中创建一个标签显示传递的参数
label = tk.Label(new_window, text=f"参数1: {param1}, 参数二: {param2}")
label.pack(padx=10, pady=10)
button = tk.Button(new_window, text="Close", command=new_window.destroy)
button.pack(pady=10)
# 创建主窗口
root = tk.Tk()
root.title("主窗口")
root.geometry("300x200")
# 在主窗口中添加一个按钮,点击后打开新的 Toplevel 窗口
open_button = tk.Button(root, text="打开子窗口", command=lambda: open_new_window("Hello", "Toplevel"))
open_button.pack(padx=20, pady=20)
# 运行应用程序
root.mainloop()
3. 子窗口打开时不能操作主窗口
import tkinter as tk
def open_new_window():
# 创建新的 Toplevel 窗口
new_window = tk.Toplevel(root)
new_window.title("子窗口")
new_window.geometry("250x150")
# 不能操作主窗口
new_window.grab_set()
# 在新窗口中添加一些控件
label = tk.Label(new_window, text="这是一个子窗口")
label.pack(padx=20, pady=20)
button = tk.Button(new_window, text="Close", command=new_window.destroy)
button.pack(pady=10)
# 创建主窗口
root = tk.Tk()
root.title("主窗口")
root.geometry("300x200")
# 在主窗口中添加一个按钮,点击后打开新的 Toplevel 窗口
open_button = tk.Button(root, text="打开子窗口", command=open_new_window)
open_button.pack(padx=20, pady=20)
# 运行应用程序
root.mainloop()
4. 捕获窗口关闭事件
import tkinter as tk
def open_window_with_protocol():
def on_closing():
print("子窗口关闭了")
window.destroy()
window = tk.Toplevel(root)
window.title("子窗口")
window.geometry("250x150")
# 设置关闭窗口的协议
window.protocol("WM_DELETE_WINDOW", on_closing)
# 添加控件到窗口
label = tk.Label(window, text="这是一个子窗口")
label.pack(pady=20)
# 创建主窗口
root = tk.Tk()
root.title("主窗口")
root.geometry("300x200")
# 添加按钮以打开窗口
protocol_button = tk.Button(root, text="打开子窗口", command=open_window_with_protocol)
protocol_button.pack(pady=20)
root.mainloop()
Label显示文本或图片组件
Label组件常用选项
text
: 标签显示的文本内容。font
: 设置文本的字体、大小等(例如("Arial", 16)
)。fg
: 设置文本颜色(例如"blue"
)。bg
: 设置标签背景颜色(例如"lightyellow"
)。width
: 标签的宽度(以字符数为单位)。height
: 标签的高度(以字符数为单位)。anchor
: 文本对齐方式(例如"w"
表示左对齐,"e"右对齐
,"center"居中
)。padx
: 文本和标签边缘之间的水平间距。pady
: 文本和标签边缘之间的垂直间距。image
: 显示图像(需要PhotoImage
或BitmapImage
对象)。compound
: 文本和图像的组合方式。top: 图片在上,文字在下。 bottom: 图片在下,文字在上。 left: 图片在左,文字在右。 right: 图片在右,文字在左。 center: 图片和文字重叠(默认值)。
Label组件示例
1. 创建一个Label组件,显示文本
import tkinter as tk
# 创建主窗口
root = tk.Tk()
root.title("Label 示例")
root.geometry("300x200")
# 创建一个标签组件
label = tk.Label(root, text="Hello, Tkinter!", font=("Arial", 16), fg="blue", bg="lightyellow")
# 使用 pack 布局管理器放置标签
label.pack(padx=20, pady=20)
# 运行主事件循环
root.mainloop()
2. 文本太长,自动换行
import tkinter as tk
# 创建主窗口
root = tk.Tk()
root.title("自动换行示例")
root.geometry("300x200")
# 创建 Label,设置宽度和自动换行
label = tk.Label(root, text="这是一个很长的文本,它会根据指定的宽度自动换行显示。", wraplength=150)
label.pack()
# 运行主事件循环
root.mainloop()
3. 带边框和内间距间隔
import tkinter as tk
# 创建主窗口
root = tk.Tk()
root.title("设置边框和填充示例")
root.geometry("300x200")
# 创建 Label,设置边框宽度和填充
label = tk.Label(root, text="带边框和填充的标签", borderwidth=1, relief="solid", padx=10, pady=10)
label.pack()
# 运行主事件循环
root.mainloop()
4. Label的点击事件
import tkinter as tk
# 定义点击事件处理程序
def on_label_click(event):
print("Label clicked!")
# 创建主窗口
root = tk.Tk()
root.title("Label 点击事件示例")
root.geometry("300x200")
# 创建标签组件
label = tk.Label(root, text="Click me!")
label.pack(padx=20, pady=20)
# 绑定鼠标左键点击事件(<Button-1> 代表左键点击)
label.bind("<Button-1>", on_label_click)
# 运行主事件循环
root.mainloop()
5. 显示图片
import tkinter as tk
from PIL import Image, ImageTk
# 创建主窗口
root = tk.Tk()
root.title("Label 显示 JPEG 图片示例")
# 加载 JPEG 图片
image = Image.open("static/background/a.jpg")
photo = ImageTk.PhotoImage(image)
# 创建 Label 并设置图片
label = tk.Label(root, image=photo)
label.pack(padx=20, pady=20)
# 保持对 Image 和 PhotoImage 的引用,防止被垃圾回收
label.image = photo
# 运行主事件循环
root.mainloop()
6. 显示图片,图片大小不超过Label组件大小,图片不变形百分比缩放
import tkinter as tk
from PIL import Image, ImageTk
def resize_image(image, max_width, max_height):
# 获取图像的原始尺寸
original_width, original_height = image.size
# 计算调整后的宽度和高度
ratio = min(max_width / original_width, max_height / original_height)
new_width = int(original_width * ratio)
new_height = int(original_height * ratio)
# 调整图像大小
return image.resize((new_width, new_height), Image.LANCZOS)
# 创建主窗口
root = tk.Tk()
root.title("Label 显示图片并调整大小示例")
root.geometry("300x200")
# 设置 Label 的最大大小,百分比缩放
label_width = 300
label_height = 200
# 加载原始图片
original_image = Image.open("static/background/a.jpg")
# 调整图片大小以适应 Label
resized_image = resize_image(original_image, label_width, label_height)
photo = ImageTk.PhotoImage(resized_image)
# 创建 Label 并设置初始图片
label = tk.Label(root, image=photo, width=label_width, height=label_height)
label.pack(padx=20, pady=20)
# 保持对 PhotoImage 对象的引用
label.image = photo
# 运行主事件循环
root.mainloop()
7. 图片和文字都显示的组合
import tkinter as tk
from PIL import Image, ImageTk
def resize_image(image, max_width, max_height):
# 获取图像的原始尺寸
original_width, original_height = image.size
# 计算调整后的宽度和高度
ratio = min(max_width / original_width, max_height / original_height)
new_width = int(original_width * ratio)
new_height = int(original_height * ratio)
# 调整图像大小
return image.resize((new_width, new_height), Image.LANCZOS)
# 创建主窗口
root = tk.Tk()
root.title("Label 显示图片并调整大小示例")
root.geometry("300x200")
# 设置 Label 的最大大小,百分比缩放
label_width = 100
label_height = 120
# 加载原始图片
original_image = Image.open("static/background/a.jpg")
# 调整图片大小以适应 Label
resized_image = resize_image(original_image, label_width, label_height)
photo = ImageTk.PhotoImage(resized_image)
# 创建 Label 并设置初始图片
label = tk.Label(root, text="头像", compound="bottom", font=("Arial", 14), image=photo, width=label_width,
height=label_height)
label.pack(padx=20, pady=20)
# 保持对 PhotoImage 对象的引用
label.image = photo
# 运行主事件循环
root.mainloop()
Entry单行文本输入框组件
Entry组件常用方法
1. 基本方法
delete(first, last=None)
: 删除文本框中从first
到last
位置的字符。如果只提供first
参数,则删除该位置的单个字符。常用值包括:0
或tkinter.END
:删除所有内容。
get()
: 返回文本框中当前的内容(文本)。
insert(index, string)
: 在指定的index
位置插入文本string
。
index(index)
: 返回光标位置或索引位置,index
可以是数字、"end"
或"insert"
等。
icursor(index)
: 设置插入光标的位置,index
指定位置。
xview(*args)
: 控制文本框的水平滚动。常用于和水平滚动条 (Scrollbar
) 配合使用。2. 文本选择相关方法
select_adjust(index)
: 根据指定索引调整当前文本选择的范围。
select_clear()
: 取消当前文本选择。
select_from(index)
: 从指定的index
位置开始选择文本。
select_present()
: 检查当前是否有文本被选择,如果有则返回True
,否则返回False
。
select_range(start, end)
: 选择从start
到end
位置的文本。
select_to(index)
: 选择从文本框开始到指定的index
位置的文本。3. 光标和视图控制方法
see(index)
: 滚动文本框以确保指定的index
位置可见。
mark_set(mark, index)
: 设置一个标记(例如插入光标位置)到指定的index
位置。
mark_unset(mark)
: 删除指定名称的标记。4. 配置和属性方法
config(**options)
或configure(**options)
: 更改或获取Entry
的配置选项,如字体、背景颜色、文本颜色等。
cget(option)
: 获取指定配置选项的当前值。5. 状态检查方法
instate(statespec, callback=None, *args, **kw)
: 如果状态匹配指定的statespec
,则调用回调函数。
state(statespec=None)
: 获取或设置当前小部件的状态(如 "disabled"、"normal" 等)。6. 绑定和事件方法
bind(sequence, func, add=None)
: 绑定一个事件到文本框。例如,<Return>
可以绑定到一个回调函数来处理回车键事件。
bind_all(sequence, func, add=None)
: 绑定一个事件到所有的文本框组件。
bind_class(className, sequence, func, add=None)
: 绑定一个事件到所有属于该类的文本框组件。
unbind(sequence, funcid=None)
: 解除绑定事件。
Entry组件示例
1. 创建 Entry 组件
import tkinter as tk
# 创建主窗口
root = tk.Tk()
root.title("tkinter Entry 使用示例")
root.geometry("300x200")
# 创建标签
label = tk.Label(root, text="请输入您的名字:")
label.pack(pady=10)
# 创建 Entry 输入框并设置默认文本
entry = tk.Entry(root)
entry.insert(0, "请输入...") # 设置默认文本
# 设置输入框宽度
entry.config(width=30)
entry.pack(pady=5)
# 运行主循环
root.mainloop()
2. 限制最多输入字符数量
import tkinter as tk
# 创建主窗口
root = tk.Tk()
root.title("tkinter Entry 使用示例")
root.geometry("300x200")
# 定义最大字符数
MAX_CHARACTERS = 20
# 定义验证函数
def validate_input(text):
return len(text) <= MAX_CHARACTERS
# 创建验证命令
validate_cmd = root.register(validate_input)
# 创建标签
label = tk.Label(root, text="请输入您的名字:")
label.pack(pady=10)
# 创建 Entry 输入框并设置默认文本
entry = tk.Entry(root, validate="key", validatecommand=(validate_cmd, "%P"))
entry.insert(0, "请输入...")
entry.config(width=30)
entry.pack(pady=5)
# 运行主循环
root.mainloop()
3. 设置背景颜色
entry = tk.Entry(root, bg="lightyellow") # 设置背景色为浅黄色
4. 去除边框
entry = tk.Entry(root, borderwidth=0, relief="flat")
5. 输入框颜色与主窗口背景颜色保持一致
import tkinter as tk
# 创建主窗口
root = tk.Tk()
root.title("tkinter Entry 背景色与主窗口一致")
root.geometry("300x200")
# 设置主窗口背景色
root_bg_color = "#f0f0f0" # 主窗口背景色
# 设置主窗口的背景色
root.config(bg=root_bg_color)
# 创建标签
label = tk.Label(root, text="请输入您的名字:", bg=root_bg_color)
label.pack(pady=10)
# 创建 Entry 输入框
entry = tk.Entry(root, borderwidth=0, relief="flat", bg=root_bg_color, fg="black") # 背景色与主窗口一致,文本色为黑色
entry.insert(0, "请输入...")
entry.config(width=30)
entry.pack(pady=5)
# 运行主循环
root.mainloop()
6. 输入框只显示下边框,宽度和窗口一样宽
import tkinter as tk
def create_entry_with_bottom_border(parent):
# 创建一个包含 Entry 和下边框的 Frame
frame = tk.Frame(parent, bg="black")
# 创建 Entry 输入框
frame_entry = tk.Entry(frame, borderwidth=0, relief="flat", bg=root_bg_color)
# 重要:fill=tk.X 输入框水平填充满Frame,此时输入框大小和frame大小一致,设置输入宽高失效
# ---- pady=(0, 2):下划线的高度
frame_entry.pack(padx=0, pady=(0, 2), fill=tk.X)
frame.pack(padx=10, pady=10, fill=tk.X) # 确保 Frame 宽度填充主窗口
return frame_entry
# 创建主窗口
root = tk.Tk()
root.title("tkinter Entry 只有下边框")
root.geometry("300x200")
# 设置主窗口背景色
root_bg_color = "#f0f0f0" # 主窗口背景色
root.config(bg=root_bg_color)
# 创建标签
label = tk.Label(root, text="请输入您的名字:", bg=root_bg_color)
label.pack(pady=10)
# 使用自定义函数创建带有下边框的 Entry
entry = create_entry_with_bottom_border(root)
entry.insert(0, "请输入...") # 设置默认文本
# 运行主循环
root.mainloop()
7. 输入框只显示下边框,指定输入框的宽高
import tkinter as tk
def create_entry_with_bottom_border(parent, width, height):
# 创建一个包含 Entry 和下边框的 Frame
frame = tk.Frame(parent, bg="black", width=width, height=height)
frame.pack_propagate(False) # 防止 Frame 调整其大小以适应内部控件
# 创建 Entry 输入框
frame_entry = tk.Entry(frame, borderwidth=0, relief="flat", bg=root_bg_color)
# 重要:fill=tk.BOTH, expand=True 输入框水平垂直全部填充满Frame,
# ---- 此时输入框大小和frame大小一致,设置输入宽高失效,
# ---- pady=(0, 2):下划线的高度
frame_entry.pack(padx=0, pady=(0, 2), fill=tk.BOTH, expand=True)
frame.pack(padx=10, pady=10)
return frame_entry
# 创建主窗口
root = tk.Tk()
root.title("tkinter Entry 只有下边框")
root.geometry("300x200")
# 设置主窗口背景色
root_bg_color = "#f0f0f0" # 主窗口背景色
root.config(bg=root_bg_color)
# 创建标签
label = tk.Label(root, text="请输入您的名字:", bg=root_bg_color)
label.pack(pady=10)
# Entry 输入框的宽高
entry_width = 180
entry_height = 20
# 使用自定义函数创建带有下边框的 Entry
entry = create_entry_with_bottom_border(root, entry_width, entry_height)
entry.insert(0, "请输入...") # 设置默认文本
# 运行主循环
root.mainloop()
8. 获取输入框内容,清空输入框内容
import tkinter as tk
# 创建主窗口
root = tk.Tk()
root.title("tkinter Entry 使用示例")
root.geometry("300x200")
# 创建标签
label = tk.Label(root, text="请输入您的名字:")
label.pack(pady=10)
# 创建 Entry 输入框并设置默认文本
entry = tk.Entry(root)
entry.insert(0, "请输入姓名...") # 设置默认文本
entry.pack(pady=5)
# 设置输入框宽度
entry.config(width=30)
# 定义获取 Entry 内容的函数
def get_entry_content():
content = entry.get()
if content == "" or content == "请输入姓名...":
result_label.config(text="请先输入内容!")
else:
print("Entry 内容:", content)
result_label.config(text="当前内容: " + content)
# 定义清除 Entry 内容的函数
def clear_entry_content():
entry.delete(0, tk.END)
result_label.config(text="Entry 内容已清除")
entry.insert(0, "请输入姓名...") # 重新设置默认文本
# 定义事件处理函数:点击输入框清除默认文本
def on_entry_click(event):
if entry.get() == "请输入姓名...":
entry.delete(0, tk.END) # 清空输入框内容
# 绑定点击事件到输入框
entry.bind("<Button-1>", on_entry_click)
# 创建按钮来获取 Entry 内容
get_button = tk.Button(root, text="获取内容", command=get_entry_content)
get_button.pack(pady=5)
# 创建按钮来清除 Entry 内容
clear_button = tk.Button(root, text="清除内容", command=clear_entry_content)
clear_button.pack(pady=5)
# 显示当前内容的标签
result_label = tk.Label(root, text="")
result_label.pack(pady=10)
# 运行主循环
root.mainloop()
Text多行文本输入框组件
Text组件常用属性
height
: 设置Text
组件的行数(高度),即可见的文本行数。
width
: 设置Text
组件的列数(宽度),即可见的字符数。
bg
或background
: 设置文本框的背景颜色。
fg
或foreground
: 设置文本的前景颜色(文本颜色)。
font
: 设置文本的字体和大小。例如,"Helvetica 12"
。
wrap
: 设置文本的换行模式。可能的值有"word"
(按单词换行)和"char"
(按字符换行)。
undo
: 设置是否启用撤销功能(布尔值)。
state
: 设置Text
组件的状态,可以是"normal"
(正常编辑)、"disabled"
(禁用编辑)或"hidden"
(隐藏文本)。
insertbackground
: 设置插入符(光标)的颜色。
spacing1
: 设置段落顶部的额外行间距,单位像素。
spacing2
: 设置行与行之间的额外行间距,单位像素。没有文字和文字水平间距。
spacing3
: 设置段落底部的额外行间距,单位像素。
tabs
: 设置制表符的间距。
selectbackground
: 设置选中文本的背景颜色。
selectforeground
: 设置选中文本的前景颜色。
insertborderwidth
: 设置插入符的边框宽度。
padx
和pady
: 设置文本框内容的内边距(水平和垂直方向)。
Text组件常用方法
1. 基础文本操作
insert(index, text, *tags)
: 在指定的index
位置插入文本,可以选择性地添加标签。delete(index1, index2=None)
: 删除从index1
到index2
的文本。如果没有提供index2
,只删除index1
处的一个字符。get(index1, index2=None)
: 获取从index1
到index2
的文本。如果没有提供index2
,只获取index1
处的一个字符。replace(index1, index2, text)
: 替换从index1
到index2
的文本为新的text
。2. 索引和位置操作
index(index)
: 返回index
的标准格式。search(pattern, index, *options)
: 在文本中搜索模式pattern
,从index
开始。可以使用regexp
选项进行正则表达式搜索。3. 选区和剪贴板
tag_add(tagName, index1, index2=None)
: 在指定的文本范围(从index1
到index2
)内添加一个标签。tag_remove(tagName, index1, index2=None)
: 从指定的文本范围(从index1
到index2
)内移除一个标签。tag_config(tagName, **options)
: 配置标签的属性,如字体、颜色等。tag_names(index=None)
: 返回在指定index
位置存在的所有标签。tag_ranges(tagName)
: 返回具有指定tagName
的所有文本范围。tag_delete(tagName)
: 删除指定的标签。tag_bind(tagName, sequence, function, add=None)
: 绑定事件处理器到指定的标签。tag_unbind(tagName, sequence, funcid=None)
: 解除标签上绑定的事件。4. 格式化和外观
mark_set(markName, index)
: 设置或移动名为markName
的标记到指定的index
。mark_unset(markName)
: 删除指定的标记。mark_names()
: 返回所有标记的列表。mark_next(index)
: 返回紧跟index
之后的标记名称。mark_previous(index)
: 返回紧接在index
之前的标记名称。mark_gravity(markName, direction)
: 设置标记的重力方向("left" 或 "right")。5. 滚动和视图
see(index)
: 确保指定的index
位置可见。yview(*args)
: 控制文本组件的垂直滚动。xview(*args)
: 控制文本组件的水平滚动。6. 控件状态
config(**options)
: 配置文本组件的各种选项。cget(option)
: 获取文本组件的指定选项的当前值。focus_set()
: 将输入焦点设置到文本组件。focus_get()
: 获取当前具有输入焦点的控件。bind(sequence, func, add=None)
: 将事件绑定到控件。7. 底层交互
clipboard_get(type='STRING')
: 从剪贴板获取内容。clipboard_append(text, **kw)
: 将文本追加到剪贴板。clipboard_clear()
: 清除剪贴板内容。8. 执行命令
edit_undo()
: 撤销上一个操作(如果启用了撤销)。edit_redo()
: 重做上一个操作(如果启用了撤销)。edit_reset()
: 重置撤销和重做堆栈。edit_separator()
: 在撤销堆栈中插入一个分隔符。edit_modified(arg=None)
: 获取或设置修改标志。
Text组件示例
1. 创建一个 Text 组件,高度为 5 行,宽度为 20 列
import tkinter as tk
# 创建主窗口
root = tk.Tk()
root.title("Text Widget Example")
root.geometry("300x200")
# 创建一个 Text 组件
text_widget = tk.Text(root, height=5, width=20)
text_widget.pack()
# 运行主循环
root.mainloop()
2. 插入和删除文本内容
import tkinter as tk
# 创建主窗口
root = tk.Tk()
root.title("Text Widget Example")
root.geometry("300x200")
# 创建一个 Text 组件,高度为 5 行,宽度为 20 列
text_widget = tk.Text(root, height=5, width=20)
text_widget.pack()
# 插入文本
text_widget.insert(tk.END, "Hello, Tkinter!\n")
text_widget.insert(tk.END, "这是一个文本组件.哈哈哈哈")
# 删除文本,从第1行的第0个字符到第1行的第5个字符
text_widget.delete("1.0", "1.5")
# 运行主循环
root.mainloop()
3. 获取文本内容
import tkinter as tk
# 创建主窗口
root = tk.Tk()
root.title("Text Widget Example")
root.geometry("300x200")
# 创建一个 Text 组件,高度为 5 行,宽度为 20 列
text_widget = tk.Text(root, height=5, width=20)
text_widget.pack()
# 插入文本
text_widget.insert(tk.END, "这是一个文本组件.哈哈哈哈")
# 获取文本内容
all_text = text_widget.get(1.0, tk.END)
print(all_text)
# 运行主循环
root.mainloop()
4. 插入带格式的文本
import tkinter as tk
# 创建主窗口
root = tk.Tk()
root.title("Text")
root.geometry("300x200")
# 创建一个 Text 组件,高度为 5 行,宽度为 20 列
text_widget = tk.Text(root, height=5, width=20)
text_widget.pack()
# 插入带标签的文本
text_widget.insert(tk.END, "红色加粗文本\n", "bold_red")
# 配置标签的样式
text_widget.tag_config("bold_red", foreground="red", font=("Helvetica", 12, "bold"))
# 插入带有背景色的文本
text_widget.insert(tk.END, "背景色文本\n", "highlight")
# 配置另一个标签的样式
text_widget.tag_config("highlight", background="yellow")
# 运行主循环
root.mainloop()
5. 带滚动条的多行文本框
import tkinter as tk
# 创建主窗口
root = tk.Tk()
root.title("Text")
root.geometry("300x200")
# 创建一个 Frame 来容纳 Text 和 Scrollbar
frame = tk.Frame(root)
frame.pack(padx=10, pady=10)
# 创建 Text 组件
text_widget = tk.Text(frame, height=5, width=20, wrap="none")
text_widget.pack(side=tk.LEFT, fill=tk.BOTH, expand=True) # text 显示在左边,垂直水平全部扩展
# 创建一个垂直滚动条,并将其放置在 Text 组件的内部
scrollbar = tk.Scrollbar(frame, command=text_widget.yview, bg="red") # 滚动条和text垂直滑动绑定
scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
# 将 Text 组件与滚动条进行绑定 yscrollcommand:垂直滚动条
text_widget.config(yscrollcommand=scrollbar.set)
# 插入一些文本内容以便演示
for i in range(1, 100):
text_widget.insert(tk.END, f"Line {i}\n")
# 运行主循环
root.mainloop()
6. 启用、禁用文本输入
# 禁用文本输入
text_widget.config(state=tk.DISABLED)
# 启用文本输入
text_widget.config(state=tk.NORMAL)
7. 获取文本光标位置
import tkinter as tk
# 创建主窗口
root = tk.Tk()
root.title("Text Widget Example")
root.geometry("300x200")
# 创建一个 Text 组件
text_widget = tk.Text(root, height=5, width=20)
text_widget.pack()
text_widget.insert(tk.END, "哈哈")
# 获取当前光标位置
cursor_index = text_widget.index(tk.INSERT)
print(f"光标下标: {cursor_index}")
# 在光标当前位置插入文本
text_widget.insert(cursor_index, "abcdef")
# 运行主循环
root.mainloop()
8. 绑定Ctrl+z撤销事件,一次一次的撤销,长按一直撤销
import tkinter as tk
def on_undo(event):
print("撤销上一次操作")
text_widget.edit_undo()
def on_key_press(event):
# 在每次按键后插入一个撤销分隔符,使每个字符成为独立的撤销步骤
text_widget.edit_separator()
# 创建主窗口
root = tk.Tk()
root.title("Text 撤销")
root.geometry("300x200")
# 创建一个 Text 组件
text_widget = tk.Text(root, height=5, width=20)
text_widget.pack()
# 启用撤销和重做功能
text_widget.config(undo=True)
# 取消上一次撤销的操作,用Control-y绑定,这里就不演示了
# text_widget.edit_redo()
# 绑定 Ctrl+z 撤销按钮事件
text_widget.bind("<Control-z>", on_undo)
# 绑定键盘按钮松开事件,让每输入一个字符成为独立的操作,一次撤销时只能撤销一个字符
text_widget.bind("<KeyRelease>", on_key_press)
# 运行主循环
root.mainloop()
9. 替换文本
import tkinter as tk
# 创建主窗口
root = tk.Tk()
root.title("Text 搜索和替换")
root.geometry("300x200")
# 创建一个 Text 组件
text_widget = tk.Text(root, height=5, width=20)
text_widget.insert(tk.END, "Hello World!")
text_widget.pack()
# 搜索的文本
search_text = "World"
# 替换的文本
replace_text = "Tkinter"
# 搜索文本并获取其位置
start_pos = text_widget.search(search_text, "1.0", tk.END)
print(f"Found 'example' at: {start_pos}")
# 替换文本
if start_pos:
end_pos = f"{start_pos}+{len('World')}c"
text_widget.delete(start_pos, end_pos)
text_widget.insert(start_pos, replace_text)
# 运行主循环
root.mainloop()
Frame内嵌框架组件
Frame组件常用方法
1. 方法和功能
__init__(self, master=None, cnf={}, **kwargs)
: 用于初始化一个Frame
实例。master
参数指定父容器,cnf
和kwargs
用于设置其他属性。
pack(side=TOP, fill=BOTH, expand=NO, padx=0, pady=0, anchor=CENTER, before=None, after=None)
: 用于将Frame
放置到父容器中,按指定的布局选项进行包装。
grid(row=0, column=0, sticky=N+S+E+W, padx=0, pady=0, columnspan=1, rowspan=1, ipadx=0, ipady=0, padx=0, pady=0)
: 用于将Frame
放置到父容器中的网格布局中,指定行、列和其他布局参数。
place(x=0, y=0, anchor='nw', bordermode='inside', relx=0.0, rely=0.0, relwidth=1.0, relheight=1.0, width=None, height=None)
: 用于将Frame
放置在父容器中的指定位置,支持绝对和相对位置设置。
pack_propagate(False)
: pack布局时,是否自动调整大小以适应内部组件。
grid_propagate(False)
: grid布局时,是否自动调整大小以适应内部组件。
config(**kwargs)
: 用于更新Frame
的配置选项,类似于configure
方法。
cget(option)
: 用于获取Frame
的指定选项的当前值。
configure(**kwargs)
: 用于设置Frame
的选项,如background
、borderwidth
等。
destroy()
: 销毁Frame
,并移除其所有子控件。
update()
: 更新Frame
的显示,通常在修改Frame
的配置后调用。
update_idletasks()
: 更新Frame
的空闲任务队列,确保所有挂起的任务(如布局调整)被处理。
unbind(sequence=None, funcid=None)
: 解除与指定事件序列相关联的回调函数。
bind(sequence=None, func=None, add=None)
: 将指定事件序列绑定到回调函数,使得事件发生时调用该函数。
forget()
: 从布局管理器中移除Frame
,但不会销毁Frame
或其子控件。
wait_variable(variable)
: 等待指定的 Tkinter 变量的值发生变化。
wait_window(window)
: 等待指定的窗口(通常是对话框)关闭。2. 常见配置选项
background
或bg
: 设置Frame
的背景颜色。borderwidth
或bd
: 设置Frame
的边框宽度。relief
: 设置Frame
的边框样式(如flat
、raised
、sunken
、groove
、ridge
)。3. 布局管理
pack()
: 控制控件的排列方式。grid()
: 控制控件的网格布局。place()
: 控制控件的位置和大小。
Frame组件示例
1. 创建一个固定大小的 Frame
import tkinter as tk
root = tk.Tk()
root.title("Frame 框架")
root.geometry("300x200")
# 创建第一个 Frame
frame = tk.Frame(root, bg="lightgray", width=150, height=100)
frame.pack_propagate(False) # 防止 Frame 调整其大小以适应内部控件
frame.place(x=20, y=20)
label1 = tk.Label(frame, text="Frame")
label1.pack(padx=10, pady=10)
root.mainloop()
2. 在 Frame 框架中来排列组件 Grid 布局
import tkinter as tk
root = tk.Tk()
root.title("Grid Layout in Frame")
root.geometry("300x200")
# 创建一个 Frame
frame = tk.Frame(root)
frame.pack(padx=10, pady=10)
# 在 Frame 中使用 grid 布局。 sticky="e":右侧对齐
tk.Label(frame, text="姓名:").grid(row=0, column=0, padx=5, pady=5, sticky="e")
tk.Entry(frame).grid(row=0, column=1, padx=5, pady=5)
tk.Label(frame, text="年龄:").grid(row=1, column=0, padx=5, pady=5, sticky="e")
tk.Entry(frame).grid(row=1, column=1, padx=5, pady=5)
# columnspan:跨越2列
tk.Button(frame, text="提交").grid(row=2, column=0, columnspan=2, pady=10)
root.mainloop()
3. Pack 布局,平分父窗口
import tkinter as tk
root = tk.Tk()
root.title("Frames with Pack Layout")
root.geometry("300x200")
# 创建第一个 Frame
frame1 = tk.Frame(root, bg="lightblue")
frame1.pack(fill=tk.BOTH, expand=True) # fill=tk.BOTH 水平垂直方向填充,expand=True外部也填充占满整父窗口
label1 = tk.Label(frame1, text="This is Frame 1")
label1.pack(pady=10)
# 创建第二个 Frame
frame2 = tk.Frame(root, bg="lightgreen")
frame2.pack(fill=tk.BOTH, expand=True)
label2 = tk.Label(frame2, text="This is Frame 2")
label2.pack(pady=10)
root.mainloop()
4. Place 布局,xy坐标指定位置
import tkinter as tk
root = tk.Tk()
root.title("Place Layout Example")
root.geometry("300x200")
# 创建一个 Frame
frame = tk.Frame(root, width=200, height=100, bg="lightyellow")
frame.place(x=50, y=50)
# 在 Frame 中放置控件
tk.Label(frame, text="This is a frame with 'place' layout", bg="lightyellow").place(x=20, y=20)
tk.Button(frame, text="Click Me").place(x=20, y=60)
root.mainloop()
5. Frame 传递参数
import tkinter as tk
def create_frame(parent, bg_color, width, height, name):
frame = tk.Frame(parent, bg=bg_color, width=width, height=height)
frame.pack_propagate(False)
frame.pack(padx=10, pady=10)
tk.Label(frame, text=name).pack(pady=10)
return frame
root = tk.Tk()
root.title("Frame 传递参数")
root.geometry("300x200")
# 创建 Frame 使用函数
create_frame(root, "lightgreen", 200, 100, "参数一 Hello")
create_frame(root, "lightcoral", 300, 150, "参数二 Frame")
root.mainloop()
6. Frame 右侧打开一个详情页
import tkinter as tk
# 创建主窗口
root = tk.Tk()
root.title("右侧详情页")
root.geometry("300x200") # 设置窗口大小
# 在窗口右侧动态添加Frame
def add_frame():
# 创建一个新的 Frame
new_frame = tk.Frame(root, bg='lightblue', width=150)
new_frame.pack_propagate(False)
new_frame.pack(side=tk.RIGHT, fill=tk.Y)
# 当前Frame没关闭,不能操作主窗口
new_frame.grab_set()
tk.Label(new_frame, text="我是详情页", bg='lightblue').pack(pady=40)
# 关闭详情页
tk.Button(new_frame, text="关闭", command=new_frame.destroy).pack()
# 打开详情页按钮
add_frame_button = tk.Button(root, text="打开详情页", command=add_frame)
add_frame_button.place(x=120, y=50)
# 运行主循环
root.mainloop()
LabelFrame内嵌框架组件
LabelFrame 和 Frame 一样,只是多了一个标题,用来区域分组。LabelFrame的相关方法和用法请到查看Frame查看。
LabelFrame 和 Frame 的区别
Frame
作用: Frame
是一个简单的容器控件,用于将其他控件分组在一起。它本身没有任何视觉效果,主要用于组织和管理布局。用法:通常用来创建应用程序的布局,或者用作容器来分组和组织控件。 LabelFrame
作用: LabelFrame
是Frame
的一种特殊形式,它除了作为容器外,还提供了一个标签(文字)作为标题。这个标签通常显示在框架的顶部,并且可以用于描述或命名框架中的控件。用法:通常用来创建具有标题的分组区域,可以使界面更具结构性和可读性。
LabelFrame示例
import tkinter as tk
root = tk.Tk()
root.title("LabelFrame")
root.geometry("500x200")
# 创建一个Frame,用来放两个LabelFrame
frame1 = tk.Frame(root)
frame1.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
labelframe1 = tk.LabelFrame(frame1, text="分组一", padx=10, pady=10)
labelframe1.pack(padx=10, pady=0, fill="both", expand=True)
labelframe2 = tk.LabelFrame(frame1, text="分组二", padx=10, pady=10)
labelframe2.pack(padx=10, pady=10, fill="both", expand=True)
# 创建第二个Frame,用来放两个LabelFrame
frame2 = tk.Frame(root)
frame2.pack(side=tk.RIGHT, fill=tk.BOTH, expand=True)
labelframe3 = tk.LabelFrame(frame2, text="分组三", padx=10, pady=10)
labelframe3.pack(padx=10, pady=0, fill="both", expand=True)
labelframe4 = tk.LabelFrame(frame2, text="分组四", padx=10, pady=10)
labelframe4.pack(padx=10, pady=10, fill="both", expand=True)
root.mainloop()
Canvas画布组件
Canvas组件常用方法
创建 Canvas 对象
canvas = Canvas(parent, width=200, height=100) parent 是 Canvas 的父组件(通常是 Tk 或 Frame)。 width 和 height 是画布的宽度和高度。 绘制直线
canvas.create_line(x1, y1, x2, y2, options…) 绘制从 (x1, y1)
到(x2, y2)
的直线。绘制矩形
canvas.create_rectangle(x1, y1, x2, y2, options…) 绘制一个矩形,左上角坐标为 (x1, y1)
,右下角坐标为(x2, y2)
。绘制椭圆形
canvas.create_oval(x1, y1, x2, y2, options…) 绘制一个椭圆,包围矩形的区域是 (x1, y1)
到(x2, y2)
。绘制多边形
canvas.create_polygon(x1, y1, x2, y2, …, options…) 绘制一个由多个顶点组成的多边形。 绘制文本
canvas.create_text(x, y, text="文本", options…) 在 (x, y)
位置绘制文本。绘制图像
canvas.create_image(x, y, image=image, options…) 在 (x, y)
位置显示图像,其中image
是一个PhotoImage
或BitmapImage
对象。绘制图形时的参数说明
canvas.create_*(x1, y1, x2, y2, fill, outline, width, font) fill: 设置图形的填充颜色,例如 fill='red'
outline: 设置图形的边框颜色,例如 outline='black'
width: 设置图形的边框宽度,例如 width=2
font: 设置文本的字体,例如 font=('Helvetica', 12)
获取图形标签
tags = canvas.gettags(tag_or_id) 获取图形的标签。 删除图形
canvas.delete(tag_or_id) 删除指定 ID 或标签的图形。ID通过create_*方法会返回一个图形的唯一 ID。 移动图形
canvas.move(tag_or_id, x, y) 将指定 ID 或标签的图形移动 (x, y)
像素。调整图形属性
canvas.itemconfig(tag_or_id, option=value) 调整图形的属性,如颜色、字体等。 获取或设置图形位置
coords = canvas.coords(tag_or_id) 取指定图形的坐标信息。 画布事件绑定
canvas.bind("<Button-1>", callback_function) 绑定鼠标左键单击事件到 callback_function
。画布解绑事件
canvas.unbind("<Button-1>") 解绑鼠标左键单击事件。 图形事件绑定
canvas.tag_bind(tag, sequence, callback) 绑定事件序列到标签 tag
的图形项上,并指定回调函数callback
。图形事件解绑
canvas.tag_unbind(tag, sequence) 解除标签 tag
上的事件序列的绑定。缩放图形
canvas.scale(tag_or_id, x, y, scale_x, scale_y) 以 (x, y)
为中心缩放指定 ID 或标签的图形项,按比例scale_x
和scale_y
。旋转图形
canvas.rotate(tag_or_id, angle, x, y) 以 (x, y)
为中心旋转指定 ID 或标签的图形项angle
度。获取图形的边界框
canvas.bbox(tag_or_id) 返回指定 ID 或标签的图形项的边界框 (x1, y1, x2, y2)
。将图形提升到画布最上层
canvas.tag_raise(tag_or_id) 将图形降低到画布最下层
canvas.tag_lower(tag_or_id) 获取画布上所有的图形的id列表
canvas.find_all() 根据标签或 ID 查找图形
canvas.find_withtag(tag_or_id) 更新画布
canvas.update() 强制更新画布显示,处理所有挂起的事件和界面更新。 设置画布滚动区域
canvas.configure(scrollregion=(x1, y1, x2, y2)) 坐标说明
x1: 左边的左右 x2: 左边的上下 y1: 右边的左右 y2: 右边的上下
Canvas组件示例
1.创建一个画布,显示画布边框
import tkinter as tk
root = tk.Tk()
root.title("画布")
root.geometry("300x200")
# 创建画布
canvas = tk.Canvas(root, width=280, height=180, bg="white", borderwidth=2, relief="solid")
canvas.pack_propagate(False)
canvas.pack()
root.mainloop()
2. 绘制图形
import tkinter as tk
root = tk.Tk()
root.title("画布")
root.geometry("320x220")
canvas = tk.Canvas(root, width=300, height=200, bg="white", borderwidth=2, relief="solid")
# 绘制直线 x1,左边的左右 x2:左边上下,y1:右边的左右 y2:右边上下
canvas.create_line(10, 10, 290, 10, fill="blue", width=2)
# 绘制矩形 x1,左边的左右 x2:左边上下,y1:右边的左右 y2:右边上下
canvas.create_rectangle(10, 20, 290, 50, outline="black", fill="red")
# 绘制椭圆形 x1,左边的左右 x2:左边上下,y1:右边的左右 y2:右边上下
canvas.create_oval(10, 60, 290, 100, outline="green", fill="yellow")
# 绘制文本 x:水平,y:垂直
canvas.create_text(100, 120, text="Hello, Tkinter!", font=("Arial", 16))
canvas.pack()
root.mainloop()
3. 绘制图像,图片不变形百分比缩放
import tkinter as tk
from PIL import Image, ImageTk
def resize_image(image, max_width, max_height):
# 获取图像的原始尺寸
original_width, original_height = image.size
# 计算调整后的宽度和高度
ratio = min(max_width / original_width, max_height / original_height)
new_width = int(original_width * ratio)
new_height = int(original_height * ratio)
# 调整图像大小
return image.resize((new_width, new_height), Image.LANCZOS)
root = tk.Tk()
root.title("画布")
root.geometry("320x220")
# 创建画布
canvas = tk.Canvas(root, width=300, height=200, bg="white", borderwidth=2, relief="solid")
canvas.pack()
# 调整图像大小,百分比缩放
new_img_width = 100 # 新的宽度
new_img_height = 100 # 新的高度
# 加载原始图片
original_image = Image.open("static/background/a.jpg")
# 调整图片大小以适应画布
resized_image = resize_image(original_image, new_img_width, new_img_height)
photo = ImageTk.PhotoImage(resized_image)
# 在 Canvas 上绘制图像
canvas.create_image(150, 100, image=photo)
root.mainloop()
PhotoImage加载图片组件
PhotoImage组件常用方法
创建
PhotoImage
实例PhotoImage(master=None, file=None, data=None) master
: 指定父组件。file
: 指定图像文件的路径。data
: 指定图像数据的字符串,例如Base64。创建
PhotoImage
实例的副本copy() 将图像数据插入到
PhotoImage
实例的指定位置put(data, to=(x, y)) data
: 要插入的图像数据。to
: 指定插入的起始坐标 (x, y)。将
PhotoImage
实例保存为文件write(filename, format=None) filename
: 文件名。format
: 可选的,指定保存图像的格式(例如 "png")。获取图像的高度
height() 获取图像的宽度
width
PhotoImage组件示例
1. 显示图片,图片大小不变
import tkinter as tk
# 创建主窗口
root = tk.Tk()
root.title("PhotoImage 示例")
root.geometry("300x200")
# 加载图像
image = tk.PhotoImage(file="static/background/a.png")
# 创建标签并显示图像
label = tk.Label(root, image=image)
label.pack()
# 启动主事件循环
root.mainloop()
2. 在Label显示图片,调整图片大小
from tkinter import Tk, Label
from PIL import Image, ImageTk
# 创建主窗口
root = Tk()
root.title("调整图像大小")
root.geometry("300x200")
# 使用 Pillow 加载图像
original_image = Image.open("static/background/a.png")
# 调整图像大小
resized_image = original_image.resize((200, 200)) # 新尺寸为200x200像素
# 将调整大小后的图像转换为 PhotoImage
photo_image = ImageTk.PhotoImage(resized_image)
# 创建标签并显示图像
label = Label(root, image=photo_image)
label.pack()
# 启动主事件循环
root.mainloop()
PanedWindow可动态调整大小的窗口组件
什么是PanedWindow
PanedWindow是一个容器小部件,用于创建具有可调整分隔条的窗口布局。它允许你将窗口分成多个面板,并允许用户通过拖动分隔条来调整其子部件的大小。这种布局非常适合需要在多个区域间动态调整空间的应用场景。
PanedWindow组件常用属性
基本属性
orient: 指定 PanedWindow 中子部件的排列方向。tk.HORIZONTAL 表示水平排列,tk.VERTICAL 表示垂直排列。 sashwidth: 控制分隔线的宽度,默认值2像素。 sashpad: 控制分隔线与相邻子部件之间的间距,默认值0像素 sashrelief: 设置分隔线的外观样式。可能的值包括:tk.RAISED(默认), tk.SUNKEN, tk.FLAT, tk.RIDGE, tk.SOLID, tk.GROOVE。 handlesize: 控制分隔线手柄的大小,以像素为单位。默认值8像素。 handlepad: 控制手柄与分隔线之间的间距。默认值8像素 showhandle: 指示是否在分隔线的中间显示一个手柄。如果设置为 True,分隔线中间会显示一个小方块手柄,便于用户拖动。默认False opaqueresize: 控制当用户拖动分隔线时,是否实时更新子部件的大小。如果设置为 True,则拖动时子部件大小会立即更新;如果设置为 False,则拖动时会显示一个轮廓,释放鼠标后才更新子部件大小。默认True。 颜色和视觉属性
background / bg: 设置 PanedWindow 的背景颜色。 borderwidth / bd: 控制 PanedWindow 的边框宽度。默认0 relief: 设置边框的样式。可能的值包括:tk.FLAT(默认), tk.RAISED, tk.SUNKEN, tk.GROOVE, tk.RIDGE, tk.SOLID。 布局和几何管理属性
height: 设置 PanedWindow 的初始高度,以像素为单位。 width: 设置 PanedWindow 的初始宽度,以像素为单位。 cursor: 设置鼠标在 PanedWindow 上方时的光标样式,例如 'arrow', 'circle', 'cross' 等。 其他属性
takefocus: 指示 PanedWindow 是否可以通过Tab键接受键盘焦点。默认True name: 设置小部件的内部名称,通常用于调试目的。 class_: 指定 PanedWindow 的窗口类名,默认是 PanedWindow,可以在窗口管理器中用于窗口配置。
PanedWindow组件常用方法
config(self, **options) / configure(self, **options): 配置或更新 PanedWindow 的属性。可以设置背景颜色、方向、分隔线宽度、是否允许调整大小等。 add(self, child, **options): 将一个子部件(如 Frame 或 Label 等)添加到 PanedWindow 中。options 可以设置子部件的大小比例、填充方式等。 remove(self, child): 从 PanedWindow 中移除一个子部件。 forget(self, child): 与 remove 方法类似,忘记一个子部件,即从 PanedWindow 中移除它。 paneconfig(self, pane, **options): 配置或更新一个已存在的子部件的属性。pane 是子部件,options 可以设置该子部件的大小、最小尺寸等。 panecget(self, pane, option): 获取一个子部件的特定属性的值。pane 是子部件,option 是要获取的属性名称。 panes(self): 返回 PanedWindow 中所有子部件的列表。 sashpos(self, index, newpos=None): 获取或设置分隔线的位置。index 是分隔线的索引(从0开始),newpos 是可选的参数,用于设置新的位置(以像素为单位)。 pack(self, **options): 使用 pack 管理器来放置 PanedWindow。 grid(self, **options): 使用 grid 管理器来放置 PanedWindow。 place(self, **options): 使用 place 管理器来放置 PanedWindow。 bind(self, sequence=None, func=None, add=None): 绑定一个事件处理函数到PanedWindow。 unbind(self, sequence, funcid=None): 解除绑定的事件处理函数。
PanedWindow组件示例
1. 创建一个PanedWindow
import tkinter as tk
root = tk.Tk()
root.title("PanedWindow Example")
root.geometry("300x200")
# 创建一个 PanedWindow,设置为水平分隔
pw = tk.PanedWindow(root, orient=tk.HORIZONTAL)
pw.pack(fill=tk.BOTH, expand=True)
# 添加两个子部件
left = tk.Frame(pw, bg='lightblue', width=150, height=200)
pw.add(left)
right = tk.Frame(pw, bg='lightgreen', width=150, height=200)
pw.add(right)
root.mainloop()
2. 设置最小缩小尺寸
pw.add(left, minsize=100) # 设置最小宽度为100像素
3. 禁止拖动
import tkinter as tk
root = tk.Tk()
root.title("PanedWindow 不能拖动大小")
root.geometry("300x200")
# 创建一个 PanedWindow,设置为水平分隔
pw = tk.PanedWindow(root, orient=tk.HORIZONTAL)
pw.pack(fill=tk.BOTH, expand=True)
# 添加两个子部件
left = tk.Frame(pw, bg='lightblue', width=100, height=200)
pw.add(left, minsize=100) # 两个子部件的和占满整个长度,来达到禁用拖动的目的
right = tk.Frame(pw, bg='lightgreen', width=150, height=200)
pw.add(right, minsize=200) # 两个子部件的和占满整个长度,来达到禁用拖动的目的
root.mainloop()
4. 嵌套PanedWindow,类似网页的左侧菜单栏,上下导航栏
import tkinter as tk
from tkinter import PanedWindow
root = tk.Tk()
root.title("Vertical PanedWindow Example")
root.geometry("300x200")
# 创建一个垂直的 PanedWindow
vertical_paned_window = PanedWindow(root, orient=tk.VERTICAL)
vertical_paned_window.pack(fill=tk.BOTH, expand=True)
# 添加第一个 Label 到垂直的 PanedWindow
top_label = tk.Label(vertical_paned_window, text="Top Pane", bg="lightcoral")
vertical_paned_window.add(top_label)
# 嵌套一个水平的 PanedWindow 到垂直的 PanedWindow 中
horizontal_paned_window = PanedWindow(vertical_paned_window, orient=tk.HORIZONTAL)
vertical_paned_window.add(horizontal_paned_window)
# 向嵌套的水平 PanedWindow 添加两个 Label
left_label = tk.Label(horizontal_paned_window, text="Left Pane", bg="lightblue")
horizontal_paned_window.add(left_label)
right_label = tk.Label(horizontal_paned_window, text="Right Pane", bg="lightgreen")
horizontal_paned_window.add(right_label)
# 添加第三个 Label 到垂直的 PanedWindow
bottom_label = tk.Label(vertical_paned_window, text="Bottom Pane", bg="lightgoldenrodyellow")
vertical_paned_window.add(bottom_label)
root.mainloop()
Notebook选项卡组件
Notebook组件常用属性
Notebook属性
width 和 height: 指定 Notebook 的宽度和高度。可以是像素值或与其他窗口组件大小相对应的值。默认根据内容自动调整。 padding: 整数或字符串 (如 10 或 "10 5")。指定 Notebook内部内容的填充(padding)。可以是一个值(四周填充相同大小)或用空格分隔的多个值(指定各个方向的填充)。默认:0。 takefocus: style: 指定 Notebook 的样式名称,以使用 ttk.Style 中定义的样式。 cursor: 指定鼠标指针悬停在 Notebook 上时的光标形状。 state: 指定 Notebook 的状态。'normal' 表示可用,'disabled' 表示不可用。 class: 用于指定窗口部件的类名,这通常用于样式和主题设置。 tabs: 一个包含所有当前选项卡的标识符的列表,可以通过 notebook.tabs() 方法获取。 选项卡的属性:每个 Notebook 中的选项卡(Tab)也有自己的一些属性,这些属性可以在创建选项卡时设置或之后通过 tab() 方法配置。
text: 选项卡上显示的文本。默认无文本。 image: 选项卡上显示的图像。可以与 text 属性结合使用。默认None。 compound: 指定如何将 text 和 image 组合在一起。选项包括 'none', 'text', 'image', 'center', 'left', 'right', 'top', 'bottom'。 underline: 指定要下划线的字符索引(从0开始)。有助于访问键盘快捷键。默认 -1(无下划线) state: 选项卡的状态。'normal' 表示可用,'disabled' 表示不可用,'hidden' 表示隐藏(但未删除)。 sticky: 指定选项卡的内容如何在选项卡内对齐。选项包括 'n', 's', 'e', 'w' 和它们的组合。 默认: 'nswe'(填满整个区域)。
Notebook组件常用方法
notebook = ttk.Notebook(parent, **options):初始化选项卡容器。parent: 父级容器组件。**options: 可选参数,如 width、height、padding 等。 add(child):添加一个选项卡片。child:选项卡容器中放的组件 forget(tab_id): 移除一个选项卡片。tab_id:选项卡的标识符,可以是选项卡的索引(从0开始)或选项卡的窗口对象。 tab_id = event.widget.select():获取选项卡标识符。 hide(tab_id): 隐藏一个选项卡(选项卡不会被销毁)。 select(tab_id=None): 选择并切换到指定选项卡。tab_id: 要选择的选项卡标识符。如果没有提供,将返回当前选项卡的标识符。 tab(tab_id, option=None, **kw): 配置或查询选项卡的属性。option: 要查询的选项(如 'text')。如果未提供,则返回所有选项。**kw: 要设置的选项。 tabs(): 返回所有选项卡的标识符。 index(tab_id): 返回给定选项卡的索引。 enable_traversal(): 启用键盘导航(使用 Ctrl+Tab 和 Ctrl+Shift+Tab 切换选项卡)。 ttk.Style().configure('TNotebook', **options):更改Notebook的外观。 ttk.Style().configure('TNotebook.Tab', **options):更改选项卡的外观。 bind("<<NotebookTabChanged>>", callback):绑定事件,当用户更改选项卡时触发。
Notebook组件示例
1. 创建一个选项卡
import tkinter as tk
from tkinter import ttk
def on_tab_change(event):
tab_id = event.widget.select()
print("Selected tab:", notebook.index(tab_id))
# 创建主窗口
root = tk.Tk()
root.title("Notebook 选项卡")
root.geometry("300x200")
# 创建Notebook组件
notebook = ttk.Notebook(root)
# 创建两个Frame,作为两个选项卡的内容
frame1 = ttk.Frame(notebook, width=300, height=200)
frame2 = ttk.Frame(notebook, width=300, height=200)
label1 = tk.Label(frame1, text="选项卡1", bg="lightblue")
label1.pack(fill=tk.BOTH, expand=True)
label2 = tk.Label(frame2, text="选项卡2", bg="lightgreen")
label2.pack(fill=tk.BOTH, expand=True)
# 向Notebook添加选项卡
notebook.add(frame1, text="Tab 1")
notebook.add(frame2, text="Tab 2")
# 布局Notebook
notebook.pack(expand=True, fill=tk.BOTH)
# 当用户更改选项卡时触发
notebook.bind("<<NotebookTabChanged>>", on_tab_change)
# 运行主事件循环
root.mainloop()
2. 添加和删除选项卡
import tkinter as tk
from tkinter import ttk
def add_tab():
frame = ttk.Frame(notebook, width=300, height=200)
notebook.add(frame, text=f"Tab {notebook.index('end') + 1}")
def remove_tab():
if notebook.tabs():
notebook.forget(notebook.select())
# 创建主窗口
root = tk.Tk()
root.title("Add and Remove Tabs")
# 创建Notebook组件
notebook = ttk.Notebook(root)
notebook.pack(expand=True, fill='both')
# 添加初始选项卡
frame1 = ttk.Frame(notebook, width=300, height=200)
notebook.add(frame1, text="Tab 1")
# 添加按钮来动态添加和删除选项卡
button_frame = tk.Frame(root)
button_frame.pack(fill='x')
add_button = tk.Button(button_frame, text="Add Tab", command=add_tab)
add_button.pack(side='left')
remove_button = tk.Button(button_frame, text="Remove Tab", command=remove_tab)
remove_button.pack(side='left')
# 运行主事件循环
root.mainloop()
Radiobutton单选框组件
Radiobutton组件常用属性
activebackground: 鼠标光标悬停在按钮上时的背景颜色。 activeforeground: 鼠标光标悬停在按钮上时的前景(文本)颜色。 anchor: 指定按钮文本的对齐方式。选项包括 n, ne, e, se, s, sw, w, nw, 和 center。 bg 或 background: 按钮的背景颜色。 bitmap: 按钮上显示的位图图像。 borderwidth 或 bd: 按钮边框的宽度,默认值为 2。 command: 当单选按钮被选中时调用的回调函数。 cursor: 鼠标悬停在按钮上时显示的光标类型。 disabledforeground: 按钮被禁用时的前景(文本)颜色。 fg 或 foreground: 按钮文本的前景颜色。 font: 按钮文本使用的字体。 height: 按钮的高度(以文本行数或像素为单位)。 highlightbackground: 按钮未被聚焦时的高亮背景颜色。 highlightcolor: 按钮被聚焦时的高亮背景颜色。 highlightthickness: 按钮高亮边框的厚度。 image: 显示在按钮上的图像对象。它可以是 PhotoImage 或 BitmapImage 对象。 indicatoron: 如果设置为 0,则单选按钮显示为按钮形式而不是传统的单选点形式。默认值为 1(显示为单选点)。 justify: 当文本超过一行时,指定文本的对齐方式。选项包括 LEFT, CENTER, 和 RIGHT。 padx: 按钮文本与按钮边框之间的水平填充(以像素为单位)。 pady: 按钮文本与按钮边框之间的垂直填充(以像素为单位)。 relief: 按钮边框的样式。选项包括 FLAT, SUNKEN, RAISED, GROOVE, 和 RIDGE。 selectcolor: 单选按钮被选中时的标记颜色。 selectimage: 按钮被选中时显示的图像(覆盖 image 属性)。 state: 按钮的状态。可以是 NORMAL(默认),ACTIVE 或 DISABLED。 takefocus: 控制按钮是否接受键盘焦点。可以是 0(不接受),1(接受),或空字符串(默认行为)。 text: 按钮上显示的文本。 textvariable: 绑定到按钮文本的变量。如果该变量的值改变,按钮文本也会自动更新。 underline: 指定按钮文本中被下划线的字符的索引位置(从 0 开始)。默认情况下,没有字符有下划线。 value: 单选按钮被选中时关联变量(variable)的值。 variable: 一个 tkinter 变量对象(例如 IntVar 或 StringVar),用于管理多个单选按钮的选择。每个单选按钮的 variable 属性相同,value 属性不同。 width: 按钮的宽度(以字符数或像素为单位)。 wraplength: 如果文本长于指定的宽度,则文本将在此宽度处换行。
Radiobutton组件常用方法
Radiobutton组件示例
1. 基本使用示例
import tkinter as tk
def on_select():
print(f"Selected option: {var.get()}")
root = tk.Tk()
root.geometry("300x200")
# 创建一个 StringVar 用来表示多个单选按钮是一组(同组中的选择互斥)
var = tk.StringVar(value="1")
# 创建单选按钮,并设置属性
rb1 = tk.Radiobutton(
root,
text="男",
variable=var,
value="1", # value的值和 variable里value的值相同,表示默认选中
command=on_select,
font=("Arial", 12),
state=tk.DISABLED
)
rb2 = tk.Radiobutton(
root,
text="女",
variable=var,
value="2",
command=on_select,
font=("Arial", 12),
)
rb1.pack(side=tk.LEFT, padx=10, pady=5)
rb2.pack(side=tk.LEFT, padx=10, pady=5)
root.mainloop()
Checkbutton复选框组件
Checkbutton组件常用属性
text: 复选按钮上显示的文本。 variable: 绑定到复选按钮的 tkinter 变量对象(如 IntVar, StringVar, BooleanVar 等)。复选按钮的状态变化时,这个变量的值会自动更新。 onvalue: 当复选按钮被选中时,variable 变量的值。 offvalue: 当复选按钮未被选中时,variable 变量的值。 command: 当复选按钮的状态改变时要调用的函数。 state: 按钮的状态(如 NORMAL, DISABLED, ACTIVE)。 font: 文本的字体。 fg (或 foreground): 文本的前景色。 bg (或 background): 背景颜色。 selectcolor: 复选按钮方框选中时的背景颜色。 anchor: 文本在复选按钮区域内的对齐方式(如 E, W, N, S)。 justify: 多行文本的对齐方式(LEFT, CENTER, RIGHT)。 padx 和 pady: 内边距(水平和垂直)。 relief: 边框样式(如 RAISED, SUNKEN, FLAT, RIDGE, GROOVE, SOLID)。
Checkbutton组件常用方法
select(): 将复选按钮设置为选中状态。 deselect(): 将复选按钮设置为未选中状态。 toggle(): 切换复选按钮的状态(从选中到未选中或反之)。 invoke(): 程序性地触发复选按钮的命令。它会执行与复选按钮关联的 command 回调。 config() 或 configure(): 更新或获取复选按钮的配置选项。 cget(): 获取指定配置选项的值。
Checkbutton组件示例
获取Checkbutton选中的值
import tkinter as tk
# 创建主窗口
root = tk.Tk()
root.geometry('300x200')
# 回调函数:打印选中的 Checkbutton 值
def get_selected_values():
selected_options = []
if var1.get() == 1:
selected_options.append(checkbutton1.cget("text"))
if var2.get() == 1:
selected_options.append(checkbutton2.cget("text"))
if var3.get() == 1:
selected_options.append(checkbutton3.cget("text"))
print("选中:", selected_options)
# 创建变量来追踪每个 Checkbutton 的状态
var1 = tk.IntVar()
var2 = tk.IntVar(value=1) # 默认选中
var3 = tk.IntVar()
# 创建 Checkbutton
checkbutton1 = tk.Checkbutton(root, text="苹果", variable=var1)
checkbutton2 = tk.Checkbutton(root, text="橙子", variable=var2)
checkbutton3 = tk.Checkbutton(root, text="西瓜", variable=var3)
# 创建一个按钮来提交选择
submit_button = tk.Button(root, text="提交", command=get_selected_values)
# 使用 pack() 布局管理器来放置组件
checkbutton1.pack()
checkbutton2.pack()
checkbutton3.pack()
submit_button.pack()
# 进入主循环
root.mainloop()
Scale滑动条组件
Scale组件常用属性
from_: 设置滑动条的最小值。 to: 设置滑动条的最大值。 orient: 设置滑动条的方向,可以是 tk.HORIZONTAL 或 tk.VERTICAL。 length: 设置滑动条的长度(在垂直方向上为高度)。 width: 设置滑动条的宽度(在水平滑动条上为宽度)。 sliderlength: 设置滑块的长度(在水平滑动条上为高度)。 resolution: 设置滑动条的刻度分辨率。 tickinterval: 设置刻度线之间的间隔。 showvalue: 设置是否显示当前值。 variable: 绑定一个 tk.Variable 对象来显示和更新滑动条的值。
Scale组件常用方法
get(): 获取当前滑动条的值。 set(value): 设置滑动条的值。 invoke(): 启动滑动条的操作(通常用于菜单中的命令)。 configure(**kwargs): 配置或更新滑动条的属性。
Scale组件示例
1. Scale使用示例
import tkinter as tk
def on_scale_change(value):
print(f"Scale value: {value}")
root = tk.Tk()
root.geometry("300x200")
scale = tk.Scale(root,
from_=0, # 滑动条的最小值
to=100, # 滑动条的最大值
orient=tk.HORIZONTAL, # 滑动条水平方向
length=280, # 滑动条的长度
width=20, # 滑动条的宽度
sliderlength=50, # 滑动块的长度
resolution=1,
tickinterval=10, # 刻度线(滑动条下面的数字)的间隔,每隔10显示一个数字
showvalue=True # 显示当前进度值(滑动条上面的数字)
)
scale.pack()
# 绑定滑动条值变化的事件
scale.bind("<Motion>", lambda event: on_scale_change(scale.get()))
root.mainloop()
2. 动态获取进度数据
import tkinter as tk
def update_value():
current_value = scale.get()
print(f"当前进度: {current_value}")
if current_value != 100:
scale.set(current_value + 20) # 加载进度值
root.after(1000, update_value) # 每1000毫秒(即1秒)调用一次update_value函数
root = tk.Tk()
root.geometry("300x200")
scale = tk.Scale(root,
from_=0, # 滑动条的最小值
to=100, # 滑动条的最大值
orient=tk.HORIZONTAL, # 滑动条水平方向
length=280, # 滑动条的长度
width=3, # 滑动条的宽度
sliderlength=10, # 滑动块的长度
resolution=1,
showvalue=True, # 显示当前进度值(滑动条上面的数字)
)
scale.pack()
# 启动定时器以每秒更新一次值
root.after(1000, update_value) # 1000毫秒后调用update_value函数
root.mainloop()
Spinbox数值选择器组件
Spinbox是tkinter提供的一种控件,用于让用户从一系列预定义的选项中选择一个值。它通常表现为一个带有上下箭头的文本框,用户可以通过点击箭头来增加或减少当前值,也可以直接输入一个值。
Spinbox组件常用方法
未完待续。。。
作者:又逢乱世