当前位置: 首页 > news >正文

tkiner模块的初步学习

文章目录

  • 一、前言
  • 二、概念
    • 2.1 安装
    • 2.2 窗口
  • 三、小部件
    • 3.1 概述
    • 3.2 常用小部件
      • 3.2.1 Label
      • 3.2.2 Button
      • 3.2.3 Entry
      • 3.2.4 Text
      • 3.2.5 Listbox
      • 3.2.6 Checkbutton
      • 3.2.7 Radiobutton
      • 3.2.8 Scrollbar
    • 3.3 更多小部件
      • 3.3.1 Scale
      • 3.3.2 Spinbox
      • 3.3.3. Progressbar
    • 3.4 主题小部件
  • 四、几何管理
    • 4.1 Frame
    • 4.2 pack
    • 4.3 place
    • 4.4 grid
  • 五、事件处理
    • 5.1 概述
    • 5.2 bind
    • 5.3 其他方法
  • 六、复杂窗口
    • 6.1 常用窗口
    • 6.2 消息框
    • 6.3 分隔符
    • 6.4 Label Frames
    • 6.5 paned windows
    • 6.6 Notebook
    • 6.7 Treeview

一、前言

https://realpython.com/python-gui-tkinter/

https://tkdocs.com/tutorial/index.html

二、概念

2.1 安装

tinker是python内置的标准GUI框架,可跨平台使用。可使用以下命令确保Tkinter正常工作:

import tkinter as tk

tk._test()

弹出一个窗口,显示Tcl/Tk的版本为8.6,要确保不是8.4或8.5

除此之外,也可以使用其他命令获取确切版本

import tkinter as tk

version = tk.Tcl().eval('info patchlevel')
print('Tk version:', tk.TkVersion, '(Tcl version:', version, ')')
# Tk version: 8.6 (Tcl version: 8.6.12 )

2.2 窗口

画板

窗口是tkinter GUI基础元素,是所有其他GUI元素所在的容器。

import tkinter as tk

window = tk.Tk()

窗口常用的方法:

方法描述
title()设置标题
geometry()设置窗口大小
resizable(FALSE,FLASE)调整窗口大小,第一个参数控制用户是否可以修改宽度,第二个则是是否可以更改高度
destroy()关闭窗口,所有子窗口也会被关闭
attributes("-fullscreen",1)全屏
withdraw()隐藏窗口

三、小部件

3.1 概述

1️⃣有了窗口后,就可以添加部件,部件是用户与程序交互的元素,部件类型有:

部件描述
Label显示文本
Button按钮
Entry仅允许输入一行文本的文本输入框
Text允许输入多行的文本输入框
Frame对部件进行分组或在部件之间提供填充的矩形区域

命名规范:

小部件可选择的标准参数选项

选项描述
activebackground鼠标悬停时的背景颜色
activeforeground鼠标悬停时的前景颜色
anchor文本或图象在标签中的对齐方式,如n、s、e、w等
background背景颜色
foreground前景颜色
font字体样式
text显示的文本内容
relief边框样式,有flat无边框、raised凸起效果、sunken凹陷效果、groove凹槽效果、ridge立体效果
padx水平内边距
pady垂直内边距
cursor鼠标悬停时的光标样式
borderwidthbd边框宽度
state组件状态,有normal、disabled禁用、active
highlightbackground高亮背景颜色
highlightcolor高亮颜色
highlightthickness高亮边框厚度
takefocus是否可以通过键盘聚焦
underline下划线索引(指定哪个字符带有下划线)

部件设置属性的常用方式:

# 创建时直接指定
label = tk.Label(root, text="Hello", bg="yellow", font=("Arial", 14))

# 通过config方法动态修改
button.config(bg="red", state="disabled")  # 禁用按钮并变红

# 通过绑定变量控制
text_var = tk.StringVar()
entry = tk.Entry(root, textvariable=text_var)
text_var.set("默认文本")  # 动态更新输入框内容

2️⃣创建部件后,还需要将部件添加到窗口中,在几何管理器一节详细介绍:

方法描述
pack()
grid()不推荐,布局难管理,没有响应式布局
place()推荐使用

3️⃣最后还需执行事件循环来监听事件

window.mainloop()

3.2 常用小部件

3.2.1 Label

可使用Label小部件来添加文本,格式为Label(master=None, cnf={}, **kw)

  1. master为父容器
  2. cnf为配置字典,用于传递配置选项,通常与**kw参数互斥
  3. **kw为关键字参数,用于传递配置选项,支持标准选项和特定于小部件的选项,推荐使用

文本部件特定选项:

特定选项描述
height高度(以文本行为单位)
width宽度(以字符为单位)
justify多行文本对齐方式,有left、center等
wraplength文本自动换行的宽度,以像素为单位

添加文本部件

greeting = tk.Label(text='Hello, world!')
greeting.pack()
window.mainloop()

为文本部件添加一些样式

label = tk.Label(
    root,
    text="欢迎使用 Tkinter",
    font=("Arial", 16),
    foreground="white",
    background="blue",
    width=20,
    height=2,
    anchor="center",
    relief="solid",
    borderwidth=2
)
label.pack(pady=20)
root.mainloop()

3.2.2 Button

小部件Button可用于显示可点击按钮,格式为Button(master=None, cnf={}, **kw)

特定选项描述
command绑定到按钮上的回调函数(点击时触发)
compound图文混合时的排列方式,有left、right、top、bottom、center
default指定按钮是否为默认按钮,有normal、active、disabled
height高度(以文本行为单位)
overrelief鼠标悬停时的边框样式
image显示图片,需要配合PhotoImage使用
width宽度(以字符为单位)

尝试使用Button小部件:

import tkinter as tk

def on_button_click():
    print("按钮被点击了!")

root = tk.Tk()
button = tk.Button(
    root,
    text="点击我",
    font=("Arial", 14),
    foreground="white",
    background="blue",
    width=10,
    height=2,
    anchor="center",
    relief="raised",
    borderwidth=2,
    command=on_button_click  # 绑定点击事件
)
button.pack(pady=20)
root.mainloop()

3.2.3 Entry

使用Entry小部件获取用户输入,格式为Entry(master=None, cnf={}, **kw)

特定选项描述
exportselection是否将选中的文本导出到系统剪贴板
insertbackground插入光标的颜色
insertborderwidth插入光标的边框宽度
insertwidth插入光标的宽度
selectbackground选中文本的背景颜色
selectborderwidth选择文本的边框宽度
selectforeground选中文本的前景颜色
show显示替代字符,如密码输入时显示*
validate指定何时进行验证,如none、focus、focusin、focusout、key
validatecommandvcmd验证输入时调用的回调函数
invalidcommandinvcmd验证失败时调用的回调函数
textvariable与Entry关联的变量

关于validatecommand参数使用:

1️⃣注册验证函数:使用root.register(validation_function) 注册验证函数,返回一个命令对象。验证函数需要返回一个布尔值(True 或 False),表示输入是否有效

2️⃣指定验证触发时机:使用validate参数指定验证触发时机,常见的有:

描述
none不进行验证
focus焦点进入或离开时
focusin焦点进入时
focusout焦点离开时
key每次按键
all上述所有情况

3️⃣传递验证参数:常见的有

描述
%P表示输入框的新值
%S插入的字符
%V验证触发的原因
%W小部件的名称
%i插入字符的位置
%d动作类型,1表示插入;0表示删除

尝试使用Entry小部件来验证输入:

import tkinter as tk

def validate_input(new_value):
    """验证输入是否为数字"""
    if new_value.isdigit() or new_value == "":
        return True
    return False

root = tk.Tk()
root.title("Entry 示例")

# 创建一个 StringVar 变量,用于绑定 Entry 的内容
entry_var = tk.StringVar()

# 配置 validatecommand
vcmd = (root.register(validate_input), '%P')  # %P 表示新值

entry = tk.Entry(
    root,
    textvariable=entry_var,
    font=("Arial", 14),
    foreground="black",
    background="white",
    width=20,
    justify="center",
    validate="key",  # 在按键时验证
    validatecommand=vcmd,  # 验证命令
    show=""  # 显示原始输入
)
entry.pack(pady=20)

root.mainloop()

除此之外,Entry还可以对用户输入的数据进行操作:

操作描述
get()检索文本
delete(first,last=None)删除文本,可以删除单个字符,也可以删除多个字符工作原理与字符串切片类似。
insert(index,text)插入文本
Select_clear()清空文本框

举个栗子:创建Entry部件,当中输入框里输入值时,控制台会打印输入的文本

import tkinter as tk

def get_entry_value():
    name = entry.get()
    print("输入的值:", name)

def delete_entry_value():
    entry.delete(0, tk.END)
    print("已删除所有内容")

def insert_entry_value():
    entry.insert(0, "python")
    print("已插入 'python'")

window = tk.Tk()
entry = tk.Entry(window, font=("Arial", 14))
entry.pack(pady=20)

button1 = tk.Button(window, text="获取输入", command=get_entry_value)
button1.pack(pady=10)

button2 = tk.Button(window, text="删除输入", command=delete_entry_value)
button2.pack(pady=10)

button3 = tk.Button(window, text="增加输入", command=insert_entry_value)
button3.pack(pady=10)

window.mainloop()

3.2.4 Text

Text小部件用于输入文本,与Entry小部件相似,不同之处在于Text小部件可包含多行文本

特定选项描述
setgrid是否设置网络
xscrollcommand与水平滚动条关联的命令
yscrollcommand与垂直滚动条关联的命令
autoseparators是否自动插入分隔符
spacing1段落前的间距
spacing2段落间的间距
spacing3段落后的间距
undo是否启用撤销功能,可以通过text.edit_undo()text.edit_redo()进行撤销和重做操作
maxundo最大撤销操作数
wrap文本换行方式,有none不换行、char按字符换行、word按单词换行
height高度(以文本行为单位)
tabs制表符宽度

尝试使用Text小部件:

import tkinter as tk

root = tk.Tk()
root.title("Text 示例")

text = tk.Text(
    root,
    font=("Arial", 14),
    foreground="black",
    background="white",
    width=40,
    height=10,
    wrap="word",  # 按单词换行
    undo=True,  # 启用撤销功能
    insertbackground="blue",  # 插入光标颜色
    insertwidth=2,  # 插入光标宽度
    highlightbackground="lightgray",
    highlightcolor="gray",
    highlightthickness=2,
    padx=10,
    pady=10,
    relief="groove",
    state="normal",
    xscrollcommand=None,
    yscrollcommand=None
)
text.pack(pady=20)

root.mainloop()

同样的,Text与Entry一样可以对用户的输入进行操作

方法描述
get(位置)获取文本(包括换行符),其中获取单个字符"行号.字符位置"行号以1开始,字符位置以0开始,多个字符需要起始索引和结束索引。
delete(位置)删除文本,可以删除单个字符,也可以删除多个字符工作原理与字符串切片类似。
insert(位置,文本)插入文本,如果要将文本插入到新行,需要在插入的文本中增加换行符
import tkinter as tk

def get_text_value():
    name = text.get("1.0",tk.END)
    print("输入的值:", name)

def delete_text_value():
    text.delete("1.0", tk.END)
    print("已删除所有内容")

def insert_text_value():
    text.insert("1.0", "python")
    print("已插入 'python'")

root = tk.Tk()

text = tk.Text(root, font=("Arial", 14))
text.pack(pady=20)

button1 = tk.Button(root, text="获取输入", command=get_text_value)
button1.pack(pady=10)

button2 = tk.Button(root, text="删除输入", command=delete_text_value)
button2.pack(pady=10)

button3 = tk.Button(root, text="增加输入", command=insert_text_value)
button3.pack(pady=10)

root.mainloop()

3.2.5 Listbox

Listbox列表框允许用户选择一个或多个,格式Entry(master=None, cnf={}, **kw)

特定选项描述
listvariable与Listbox关联的变量,通常使用StringVar或Variable
selectmode选择模式,有single单选、browse单选但可以通过Shift键选择范围、multiple多选、extended单选但可以通过Shift键选择范围或者通过Ctrl键选择多个
activestyle选中项的高亮模式,有dotbox、none

除此之外,还有以下常用方法:

方法描述
insert(index,*elements)在指定位置插入新项目
get(first,last=None)获取指定范围内的项目内容
delete(first,last=None)删除指定范围内的项目
curselection()返回当前选中的项目索引列表

使用实例

import tkinter as tk

root = tk.Tk()

# 创建 Listbox
listbox = tk.Listbox(root)
listbox.pack(fill="both", expand=True)

# 插入项目
for i in range(10):
    listbox.insert(tk.END, f"项目 {i+1}")

# 设置选中状态
listbox.selection_set(2, 4)  # 选中索引 2 到 4 的项目

# 滚动到指定项目
listbox.see(8)  # 确保索引为 8 的项目可见

# 获取选中的项目
selected_indices = listbox.curselection()
print("选中的项目索引:", selected_indices)

# 获取项目总数
count = listbox.size()
print("项目总数:", count)

# 修改项目样式
listbox.itemconfigure(1, background="green", foreground="white")

root.mainloop()

3.2.6 Checkbutton

Checkbutton用于勾选选项,格式为Checkbutton(master=None, cnf={}, **kw)

特定选项描述
command绑定回调函数
onvalue选中时的值,默认为1
offvalue未选中时的值,默认为0
variable与Checkbutton关联的变量,通常使用IntVar或BooleanVar
indicatoron是否显示复选框的小方块
selectcolor小方块内勾选的颜色
import tkinter as tk

def on_checkbutton_change():
    print("Checkbutton 状态:", var.get())

root = tk.Tk()
root.title("Checkbutton 示例")

# 创建一个 IntVar 变量,用于绑定 Checkbutton 的状态
var = tk.IntVar()

checkbutton = tk.Checkbutton(
    root,
    text="选择我",
    variable=var,
    command=on_checkbutton_change,
    font=("Arial", 14),
    foreground="black",
    background="white",
    width=20,
    height=2,
    anchor="w",
    relief="groove",
    borderwidth=2,
    state="normal",
    offvalue=0,
    onvalue=1,
    selectcolor="lightblue",
    underline=0
)
checkbutton.pack(pady=20)

root.mainloop()

3.2.7 Radiobutton

Radiobutton用于创建一组互斥的选项按钮,用户只能从中选择一个

特定选项描述
command绑定回调函数
value单选按钮的值
variable与Radiobutton关联的变量,通常使用IntVar或BooleanVar
import tkinter as tk

def on_radiobutton_change():
    print("选中的值:", var.get())

root = tk.Tk()
root.title("Radiobutton 示例")

# 创建一个 IntVar 变量,用于绑定 Radiobutton 的状态
var = tk.IntVar()

# 创建 Radiobutton 小部件
radiobutton1 = tk.Radiobutton(
    root,
    text="选项 1",
    variable=var,
    value=1,
    command=on_radiobutton_change,
    font=("Arial", 14),
    foreground="black",
    background="white",
    width=20,
    height=2,
    anchor="w",
    relief="groove",
    borderwidth=2,
    state="normal",
    selectcolor="lightblue",
    underline=0
)
radiobutton1.pack(pady=10)

radiobutton2 = tk.Radiobutton(
    root,
    text="选项 2",
    variable=var,
    value=2,
    command=on_radiobutton_change,
    font=("Arial", 14),
    foreground="black",
    background="white",
    width=20,
    height=2,
    anchor="w",
    relief="groove",
    borderwidth=2,
    state="normal",
    selectcolor="lightblue",
    underline=0
)
radiobutton2.pack(pady=10)

root.mainloop()

3.2.8 Scrollbar

Scrollbar滚动条可以帮助用户查看另一个部件的剩余部分

特定选项描述
orient滚动条的方向,tk.VERTICAL表示垂直滚动条;tk.HORIZONTAL表示水平滚动条
jump是否允许拖动滑块直接跳转到某个位置
troughcolor滑槽的颜色
width滚动条的宽度(以像素为单位)
command绑定回调函数,接受两个参数first、last分别表示滚动条可见区域的起始位置和结束位置,浮点数表示,范围为0到1

config方法可以用于动态修改滚动条配置选项,格式为config(cnf=None,**kw)

  1. cnf:如果为字典类型,表示要批量设置的选项,如果是字符串类型,则表示要查询的选项名称
  2. **kw:键值对形式,用于动态修改滚动条的配置

绑定滚动条与小部件的command参数:

  1. text.yview:将垂直滚动条与Text小部件的垂直滚动关联
  2. text.xview:将水平滚动条与Text小部件的水平滚动关联
import tkinter as tk

root = tk.Tk()
root.title("Scrollbar使用")

# 创建两个滚动条
scrollbar_v = tk.Scrollbar(root)
scrollbar_v.pack(side=tk.RIGHT, fill=tk.Y)
scrollbar_h = tk.Scrollbar(root, orient=tk.HORIZONTAL)
scrollbar_h.pack(side=tk.BOTTOM, fill=tk.X)

# 创建一个文本框
text = tk.Text(root, height=10, width=30, yscrollcommand=scrollbar_v.set)
text.pack(side=tk.LEFT, fill=tk.BOTH)
scrollbar_v.config(command=text.yview)
scrollbar_h.config(command=text.xview)
root.mainloop()

3.3 更多小部件

3.3.1 Scale

Scale组件允许用户直接选择数值

特定选项描述
tickinterval刻度线的间隔
resolution刻度的最小变化值,默认为1
digits显示值的小数位数
from_ 刻度的起始值
to刻度的结束值
variable与Scale关联的变量,通常使用IntVar或DoubleVar
command回调函数,会接受当前值作为参数
showvalue是否显示当前值
orient刻度的方向,有horizontal和vertical
import tkinter as tk

# 创建主窗口
root = tk.Tk()
root.title("Scale 示例")

# 定义回调函数
def on_scale_change(value):
    print(f"当前值: {value}")

# 创建水平刻度条
scale_horizontal = tk.Scale(
    root,
    from_=0,
    to=100,
    orient="horizontal",
    length=300,
    tickinterval=10,
    command=on_scale_change
)
scale_horizontal.pack(pady=20)

# 创建垂直刻度条
scale_vertical = tk.Scale(
    root,
    from_=0,
    to=100,
    orient="vertical",
    length=200,
    tickinterval=10,
    command=on_scale_change
)
scale_vertical.pack(padx=20, side="right")

# 运行主循环
root.mainloop()

3.3.2 Spinbox

Spinbox组件允许用户在给定范围内选择数字

特定参数描述
buttondownrelief向下按钮的边框样式
buttonuprelief向上按钮的边框样式
command绑定回调函数
format显示值的格式
from_ 刻度的起始值
to刻度的结束值
increment每次点击按钮值的变化量
readonlybackground只读状态下的背景颜色
validate指定何时进行验证
validatecommand验证输入时调用的回调函数
values可选值列表,优先级高于from_to
width宽度
wrap是否允许值在达到最大值后绕回到最小值
textvariable与文本关联的变量
import tkinter as tk

def on_spinbox_change(*args):
    print("当前值:", spinbox.get())

root = tk.Tk()
root.title("Spinbox 示例")

# 创建一个 IntVar 变量,用于绑定 Spinbox 的值
spinbox_var = tk.IntVar()

# 创建 Spinbox 小部件
spinbox = tk.Spinbox(
    root,
    from_=0,
    to=100,
    increment=5,
    textvariable=spinbox_var,
    command=on_spinbox_change,
    font=("Arial", 14),
    width=10,
    justify="center",
    wrap=True,
    state="normal",
    buttonbackground="lightgray",
    buttoncursor="arrow",
    buttondownrelief="sunken",
    buttonuprelief="raised",
    relief="groove",
    takefocus=True,
    validate="key",
    validatecommand=(root.register(lambda value: value.isdigit() or value == ""), "%P")
)
spinbox.pack(pady=20)

root.mainloop()

3.3.3. Progressbar

Progressbar部件用于显示进度状态,有两种模式:确定模式和不确定模式,格式:Progressbar(master=None, **kw)

参数描述
orient进度条方向,默认horizontal水平方向,vertical垂直方向
mode工作模式,有determinate确定模式,显示已完成的任务量;indeterminate不确定模式,显示动画效果,表示任务正在进行中。
maximum进度条最大值,默认为100
value设置当前进度值,仅在确定模式下有效
variable绑定一个变量
phase不常用,表示不确定模式下的动画阶段

方法介绍:

方法描述
start(interval=None)开始自动递增模式,每隔interval毫秒就调用step方法
step(amount=None)手动递增进度条的值
stop()停止自动递增模式
import tkinter as tk
from tkinter import ttk

# 创建主窗口
root = tk.Tk()
root.title("Progressbar 示例")

# 创建进度条
progress = ttk.Progressbar(root, orient="horizontal", length=300, mode="determinate")
progress.pack(pady=20)

# 初始化进度值
progress['value'] = 0

# 定义按钮点击事件
def start_progress():
    if progress['value'] < 100:
        progress['value'] += 10  # 每次增加 10
        root.after(500, start_progress)  # 每隔 500 毫秒调用一次

# 创建按钮
button = ttk.Button(root, text="开始", command=start_progress)
button.pack()

# 运行主循环
root.mainloop()

3.4 主题小部件

Tkinter目前有两大类小部件:优先使用ttk部件

  1. 经典小部件:tkinter,简单易用,例如tkinter.Label
  2. 主题小部件:ttk,默认使用操作系统的原生外观,可看作Tkinter的CSS,例如tkinter.ttk.Label

在使用Tkinter的主题部件时,通常使用以下命令

import tkinter as tk
import tkinter.ttk as ttk

尝试使用部件:

tk.Label()
ttk.Label()

也可以使用更便捷的用法,主题小部件会自动覆盖旧部件:

from tkinter import *
from tkinter.ttk import *

Label()
Text()

四、几何管理

同一窗口中只能使用一种布局管理器

4.1 Frame

空的Frame小部件实际上是不可见的,一般用来做其他小部件的容器master参数值

frame = tk.Frame()
label = tk.Label(master=frame)

Frame适合以逻辑方式布置其他小部件

import tkinter as tk

window = tk.Tk()

frame_a = tk.Frame()
frame_b = tk.Frame()

label_a = tk.Label(master=frame_a, text="I'm in Frame A")
label_a.pack()

label_b = tk.Label(master=frame_b, text="I'm in Frame B")
label_b.pack()

frame_a.pack()
frame_b.pack()

window.mainloop()

如果将frame_a.pack()frame_b.pack()的顺序调换:

4.2 pack

pack使用打包算法将小部件按指定顺序放在Frame或窗口中,是响应式布局;默认情况下将每个组件放置在前一个组件的下方

import tkinter as tk

window = tk.Tk()

frame1 = tk.Frame(master=window, width=100, height=100, bg="red")
frame1.pack()

frame2 = tk.Frame(master=window, width=50, height=50, bg="yellow")
frame2.pack()

frame3 = tk.Frame(master=window, width=25, height=25, bg="blue")
frame3.pack()

window.mainloop()

pack的一些常用参数

常用参数描述
fill指定哪个方向填充,tk.X为填充水平方向;tk.Y为填充垂直方向;使用tk.BOTH同时需要设置expand
side指定放置在窗口哪一侧,tk.TOP(默认)、tk.BOTTOMtk.LEFTtk.RIGHT

使用fill参数后填充水平方向:frame1.pack(fill=tk.X)

使用side参数后填充水平方向:frame1.pack(side=tk.LEFT, fill=tk.Y)

4.3 place

place可以控制精确位置,需要x和y参数来指定小部件左上角的x和y,以像素为单位。place很难管理布局,且没有响应式,一般不推荐使用。

import tkinter as tk

window = tk.Tk()

frame = tk.Frame(master=window, width=150, height=150)
frame.pack()

label1 = tk.Label(master=frame, text="I'm at (0, 0)", bg="red")
label1.place(x=0, y=0)

label2 = tk.Label(master=frame, text="I'm at (75, 75)", bg="yellow")
label2.place(x=75, y=75)

window.mainloop()

4.4 grid

grid通过将窗口或Frame拆分为行和列来工作

常用参数描述
row行索引
column列索引
padx水平方向上添加外部填充
pady垂直方向上添加外部填充
sticky更改网格内标签的位置,有n、w、e、s
import tkinter as tk

window = tk.Tk()

for i in range(3):
    for j in range(3):
        frame = tk.Frame(
            master=window,
            relief=tk.RAISED,
            borderwidth=1
        )
        frame.grid(row=i, column=j)
        label = tk.Label(master=frame, text=f"Row {i}\nColumn {j}")
        label.pack()

window.mainloop()

除此之外可以使用columnconfigure方法和rowconfigure方法来实现网格适应窗口变化,它们都有共同的基本参数:

  1. index:索引,要配置的网格列或者行索引,如果要配置多个则采用列表形式
  2. Weight:确定列或行要如何响应窗口(相对于其他行或列),为0时这列/行不会随窗口大小而扩展,如果都为1时以相同速率生长
  3. Minimum Size:设置行高度或列宽度的最小尺寸,以像素为单位
import tkinter as tk

window = tk.Tk()

for i in range(3):
    window.columnconfigure(i, weight=1, minsize=75)
    window.rowconfigure(i, weight=1, minsize=50)

    for j in range(0, 3):
        frame = tk.Frame(
            master=window,
            relief=tk.RAISED,
            borderwidth=1
        )
        frame.grid(row=i, column=j, padx=5, pady=5)
        label = tk.Label(master=frame, text=f"Row {i}\nColumn {j}")
        label.pack(padx=5, pady=5)

window.mainloop()

grid与pack在填充上对应关系:推荐使用grid

五、事件处理

5.1 概述

使用window.mainloop()来启动事件循环,使用bind或者command方法来绑定事件,command方法一般不接受参数。

事件发生时,会从触发该事件的小部件开始,逐级向上传播到其父容器直到根窗口,这个过程称为事件传播,如果希望阻止事件传播到父容器,可以在回调函数中返回break

Event事件对象常用属性有:

属性描述
xy事件发生的坐标(相对于组件)
x_root,y_root事件发生的坐标(相对于屏幕)
keysym按键的符号名称
widget触发事件的小部件
type事件类型
time事件发生的时间戳

事件模式由<MODIFIER-MODIFIER-TYPE-DETAIL>构成

1️⃣MODIFIER修饰符用于指定按键组合,常见的有:

修饰符描述
ControlCtrl键
AltAlt键
MetaMeta键,通常对应Windows键或Command键
ShiftShift键
LockCaps Lock键
Button1Button5鼠标按钮

2️⃣Type事件类型定义了具体的事件类型,常见的有:

事件描述
Activate窗口激活,通常指state的变化
Deactivate从活动状态变为不活动状态,通常指state的变化
Button左键点击、左键双击
ButtonRelease释放鼠标按钮
Destroy小部件销毁
Enter鼠标进入小部件区域
Leave鼠标移出部件区域
Motion鼠标拖动
FocusIn进入焦点
FocusOut退出焦点
MouseWheel滚轮滚动
Configure窗口大小或位置改变
KeyPressKey键盘按键按下
KeyRelease键盘按键释放

3️⃣DETAIL细节时对事件类型的详细补充,例如对于Button来说,1表示左键,3表示右键;而对于KeyPress来说,细节是按键的符号名称。

5.2 bind

使用bind方法来绑定事件,格式为bind(sequence=None, func=None, add=None)

  1. sequence:事件序列,由一个或多个事件模式组成,格式为<MODIFIER-MODIFIER-TYPE-DETAIL>,例如<Control-c>按下
    Ctrl + C;<<CustomEvent>>自定义虚拟事件。
  2. func:事件发生时执行的函数,接受Event实例,如果返回值为break则阻止后续函数调用。
  3. add:为True时则将新绑定函数添加到现有绑定中,如果为False则替换现有绑定。

如果绑定了事件,可以用unbind来删除绑定:widget.unbind("<事件类型>")

绑定鼠标事件:

import tkinter as tk

# 创建主窗口
root = tk.Tk()

# 定义回调函数
def on_click(event):
    print(f"鼠标点击位置: ({event.x}, {event.y})")

# 创建按钮
button = tk.Button(root, text="点击我")
button.pack(pady=20)

# 绑定鼠标左键点击事件
button.bind("<Button-1>", on_click)

# 运行主循环
root.mainloop()

虚拟事件是用户自定义的事件,通过event_generate来触发

import tkinter as tk

# 创建主窗口
root = tk.Tk()

# 定义回调函数
def on_custom_event(event):
    print("触发了自定义事件")

# 创建按钮
button = tk.Button(root, text="触发事件")
button.pack(pady=20)

# 绑定虚拟事件
button.bind("<<CustomEvent>>", on_custom_event)

# 触发虚拟事件
button.event_generate("<<CustomEvent>>")

# 运行主循环
root.mainloop()

5.3 其他方法

bind_class(class_name,sequence,func):为特定类名的小部件绑定事件

  root.bind_class("Button", "<Button-1>", lambda event: print("任意按钮点击"))

bind_all(sequence,func):为所有小部件绑定事件

  root.bind_all("<KeyPress>", lambda event: print(f"按键: {event.keysym}"))

六、复杂窗口

6.1 常用窗口

filedialog模块可以对文件或目录进行操作

from tkinter import filedialog

# 打开文件对话框
open_filename = filedialog.askopenfilename(title="选择要打开的文件")
if open_filename:
    print(f"选择的文件路径: {open_filename}")

# 保存文件对话框
save_filename = filedialog.asksaveasfilename(title="选择保存文件的位置")
if save_filename:
    print(f"保存的文件路径: {save_filename}")

# 选择文件夹对话框
dirname = filedialog.askdirectory(title="选择一个文件夹")
if dirname:
    print(f"选择的文件夹路径: {dirname}")

进行颜色选择:

from tkinter import colorchooser

# 创建颜色选择器对话框
color_chooser = colorchooser.Chooser(
    initialcolor="#ff0000",  # 初始颜色为红色
    title="选择颜色"         # 对话框标题
)
rgb, hex_color = color_chooser.show()

if rgb and hex_color:
    print(f"RGB: {rgb}, Hex: {hex_color}")
else:
    print("用户取消了颜色选择")

选择字体:

import tkinter as tk
from tkinter import ttk
def font_changed(font):
    if font:  # 如果用户没有取消选择
        print("Selected font:", font)
        label.config(font=font)

def font_choice() -> None:
    root.tk.call('tk', 'fontchooser', 'configure',
                 '-font', current_font.get(),
                 '-command', root.register(font_changed))
    root.tk.call('tk', 'fontchooser', 'show')

root = tk.Tk()
root.title("字体选择示例")
root.geometry("300x150")

current_font = tk.StringVar(value="helvetica 24")

label = ttk.Label(root,text="你好啊",font=current_font.get(),padding=(10, 10))
label.pack(pady=10)

btn = ttk.Button(root,text="选择字体",command=font_choice)
btn.pack(pady=10)

root.mainloop()

在这里插入图片描述

6.2 消息框

使用messagebox模块来应用消息提示框,有不同类型的提示框

类型描述
showinfo(title,message,**options)信息对话框
shhowwaring(title,message,**options)警告对话框
showerror(title,message,**options)错误对话框
askquestion(title,message,**options)带有是和否的问题对话框
askokcancel(title,message,**options)带有确定和取消的对话框
askyesno(title,message,**options)带有是和否的对话框
askyesnocancel(title,message,**options)带有是、否、取消的对话框
askretrycancel(title,message,**options)带有重试和取消的对话框

参数解析:

参数描述
title对话框的标题
message对话框显示的消息文本
icon显示的图标类型,有ERROR,INFO,QUESTION,WARNING
default设置默认按钮
parent指定对话框的父窗口

使用示例:

from tkinter import messagebox
messagebox.showinfo(message='Have a good day')
messagebox.askyesno(message='Are you sure you want to install SuperVirus?', 
                    icon='question', title='Install')

6.3 分隔符

使用Separator部件在小部件之间放置水平或垂直线来实现分隔

import tkinter as tk
from tkinter import ttk

root = tk.Tk()
root.title("Separator 示例")
root.geometry("300x200")

separator_horizontal_grid = ttk.Separator(root, orient=tk.HORIZONTAL)
separator_horizontal_grid.grid(row=1, column=0, sticky="ew", padx=10, pady=10)

separator_vertical_grid = ttk.Separator(root, orient=tk.VERTICAL)
separator_vertical_grid.grid(row=0, column=1, rowspan=3, sticky="ns", padx=10, pady=10)

# 添加一些标签以显示分隔线的效果
label1 = ttk.Label(root, text="标签 1")
label1.grid(row=0, column=0, padx=10, pady=10)

label2 = ttk.Label(root, text="标签 2")
label2.grid(row=2, column=0, padx=10, pady=10)

label3 = ttk.Label(root, text="标签 3")
label3.grid(row=0, column=2, padx=10, pady=10)

root.mainloop()

6.4 Label Frames

label Frames称为标签帧,一些常用参数:

参数描述
labelanchor指定标签的位置,如n顶部中间,nw左上角
padding设置内部部件与边框之间的间距
labelwidget使用自定义的小部件作为标签
class_小部件的类名,通常不需要手动设置
style小部件的样式,需要提前通过ttk.Style定义
takefocus指定小部件是否可以通过Tab键获取焦点
import tkinter as tk
from tkinter import ttk

root = tk.Tk()
root.title("Labelframe 示例")

# 创建一个 Labelframe
labelframe = ttk.Labelframe(root, text="这是一个 Labelframe", labelanchor="n")
labelframe.pack(padx=10, pady=10, fill="both", expand=True)

# 在 Labelframe 内添加其他小部件
label = ttk.Label(labelframe, text="这是 Labelframe 内部的内容")
label.pack(padx=5, pady=5)

root.mainloop()

6.5 paned windows

常用参数:

参数描述
class_小部件的类名,通常不需要手动设置
orient设置子窗口的排列方式,值为horizontalvertical
takefocus指定小部件是否可以通过Tab键获取焦点

常用方法:

方法描述
add(child,**kw)添加一个子窗口,**kw为子窗口选项(如weight权重)
insert(pos,child,**kw)在指定位置插入一个子窗口
forget(child)移除指定子窗口
sashpos(index,newpos=None)获取或设置分割条的位置,newpos为新的位置
pane(pane,option=None,**kw)查询或修改子窗口的选项,pane为子窗口索引或名称,option如果指定则返回该选项的值

使用实例

import tkinter as tk
from tkinter import ttk

# 创建主窗口
root = tk.Tk()
root.title("Panedwindow 示例")

# 创建一个水平方向的 Panedwindow
paned_window = ttk.Panedwindow(root, orient="horizontal")
paned_window.pack(fill="both", expand=True)

# 添加第一个子窗口
frame1 = ttk.Frame(paned_window, width=100, height=200, relief="sunken")
paned_window.add(frame1)

# 添加第二个子窗口
frame2 = ttk.Frame(paned_window, width=300, height=200, relief="sunken")
paned_window.insert(0, frame2)

# 查询子窗口选项
options = paned_window.pane(0)
print(options)  # {'weight': 0}

# 运行主循环
root.mainloop()

6.6 Notebook

Notebook用于管理一组窗口,同一时间只显示一个窗口,每个子窗口与一个标签关联。

参数描述
class指定窗口类名,通常不设置
style样式
padding标签之间的间距

常用方法如下所示,其中tab_id可以是标签索引(从0开始)、子窗口名称、位置规格(如@x,y表示鼠标指针所在位置的标签)、current(当前选中的标签)等

方法描述
add(child,**kw)添加新的标签页
forget(tab_id)移除指定的标签页
hide(tab_id)隐藏指定的标签页
select(tab_id=None)选择指定的标签页
insert(pos,child,**kw)指定位置插入一个标签页
enable_traversal()启用键盘导航功能,有Ctrl+Tab切换到下一个标签页等
tab(tab_id,option=None,**kw)查询或修改指定标签的选项

使用示例:

import tkinter as tk
from tkinter import ttk

root = tk.Tk()
root.title("Notebook 示例")

# 创建 Notebook
notebook = ttk.Notebook(root)
notebook.pack(fill="both", expand=True)

# 创建标签页
frame1 = ttk.Frame(notebook, width=200, height=200)
frame2 = ttk.Frame(notebook, width=200, height=200)

# 添加标签页
notebook.add(frame1, text="标签页 1")
notebook.add(frame2, text="标签页 2")

# 在标签页中添加内容
label1 = ttk.Label(frame1, text="这是标签页 1 的内容")
label1.pack(pady=20)

label2 = ttk.Label(frame2, text="这是标签页 2 的内容")
label2.pack(pady=20)

# 启用键盘导航
notebook.enable_traversal()

root.mainloop()

6.7 Treeview

Treeview用于显示分层的项目集合,构造时有以下常用参数:

参数描述
xscrollcommand绑定水平滚动条
yscrollcommand绑定垂直滚动条
columns定义除树形结构外的其他列
displaycolumns指定要显示的列(默认所有列)
selectmode设置选择模式,有browse单选模式(默认)、extended多选、none禁用选择
padding设置子项之间的间距
show指定显示的内容,有tree仅显示树形结构、headings仅显示列标题、tree headings同时显示树形结构和列标题

除此之外,常用方法有:

方法描述
delete(*items)删除指定项目极其后代
exists(item)检查指定项目是否存在
insert(parent,index,iid=None,**kw)插入新项目,parent参数里""表示根项目,iid表示项目标识符,**kw项目选项
tag_bind(tagname,sequence=None,callback=None)为指定标签绑定事件,tagname标签名称;sequence事件序列;callback回调函数

项目选项:在插入项目或者修改项目时,通常有以下选项

参数描述
text文本标签
image图象
values数据值列表,对应各列
open指定项目是否展开,可选值为True或False
tags给项目添加标签,用于绑定事件或样式

使用案例:

import tkinter as tk
from tkinter import ttk

# 创建主窗口
root = tk.Tk()
root.title("Treeview 示例")

# 创建 Treeview
tree = ttk.Treeview(root, columns=("姓名", "年龄"), show="headings")
tree.pack(fill="both", expand=True)

# 设置列标题
tree.heading("#1", text="姓名")
tree.heading("#2", text="年龄")

# 插入数据
data = [("张三", "25"), ("李四", "30"), ("王五", "22")]
for item in data:
    tree.insert("", "end", values=item)

# 添加滚动条
scrollbar = ttk.Scrollbar(root, orient="vertical", command=tree.yview)
scrollbar.pack(side="right", fill="y")
tree.configure(yscrollcommand=scrollbar.set)

# 运行主循环
root.mainloop()
http://www.dtcms.com/a/112914.html

相关文章:

  • 冷门预警,英超006:埃弗顿VS阿森纳,阿森纳分心欧冠,太妃糖或有机可乘
  • TDengine 3.3.6.0 版本中非常实用的 Cols 函数
  • Vue.js设计与实现学习
  • 走进未来的交互世界:下一代HMI设计趋势解析
  • 第九章Python语言高阶加强-面向对象篇
  • 基于Python的微博数据采集
  • 架构及大数据-Zookeeper与Kafka的关系及使用依赖,二者需要同时使用吗?KRaft模式又是啥?
  • Linux常用命令详解:从基础到进阶
  • 基于Python+Flask的服装零售商城APP方案,用到了DeepSeek AI、个性化推荐和AR虚拟试衣功能
  • DCMM详解
  • JS DOM 修改表单样式
  • 浅谈AI - DeepSpeed - 单卡慎用!
  • opencv中mat深拷贝和浅拷贝
  • 常用中间件合集
  • 深入理解 C++ 三大特性之一 继承
  • Java项目之基于ssm的孩童收养信息管理(源码+文档)
  • 详细分析单例模式
  • 【AI编程学习之Python】第五天:Python的变量和常量
  • Kafka 高吞吐量的原因是什么?
  • CNN 中感受野/权值共享是什么意思?
  • 基于Python的图书借阅推荐系统设计与实现
  • 深度学习的疑问(GNN)【1】:图采样与训练
  • html 给文本两端加虚线自适应
  • MySQL学习笔记(三)——图形化界面工具DataGrip
  • 深入解析C++智能指针:从内存管理到现代编程实践
  • Swagger @ApiOperation
  • Qt之QNetworkInterface
  • 低代码开发平台:飞帆中的控件中转区
  • AI Agent设计模式三:Routing
  • 智能合约的法律挑战与解决之道:技术与法律的交融