声明:该文章是个人学习中写的,目的是总结及当作工具参考,有一定的借鉴成分,后续若有新发现则补充
目录
Tkinter简介
创建组件基本语法
Tkinter组件汇总
Variable 类
常见参数详解
anchor——表示文本的位置
background(简称bg)——背景色
foreground(简称fg)——前景色
font——字体
布局管理器
pack
grid
place
组件详解
Label 标签
Botton 组件
LabelFrame 带有标签的框架
Entry 输入框
Listbox 列表框
Scrollbar 垂直滚动条
Scale 滚动条
Text 文本组件
Indexes 用法
Marks 用法
Tag用法
部分Text技巧
Canvas 绘图
Canvas组件支持的对象
坐标系
画布对象显示的顺序
指定画布对象
Menu 菜单
OptionMenu 选项菜单
Message 消息组件
Spinbox 组件
PanedWindow 组件
Toplevel 顶级窗口
事件
事件绑定
事件序列
type部分常用关键词及含义:
modifier部分常用的关键词及含义
Event对象
Event对象的属性及含义:
键盘所有特殊案件的keysym和keycode:
标准对话框
messagebox 消息对话框
options参数设置内容
返回值
fieldialog 文件对话框
filedialog 内置函数
filedialog 参数汇总
返回值
Tkinter是python默认的GUI库,像python IDLE就是用Tkinter设计出来的。导入时可以直接导入:
import tkinter
简单示例:
from tkinter import *
root = Tk() #实例化Tk类
Label1 = Label(root,text = 'hello') #在root中创建内容为“hello”的Label
Label1.pack() #自动调节Label1尺寸
root.mainloop() #进入消息循环
进阶示例:
import tkinter as tk
class App:
def __init__(self, root): #接收Tk的实例化对象root
frame = tk.Frame(root) #在root中创建一个Frame框架
frame.pack() #自动调节frame尺寸
#创建文字为“hello”的按钮,按下执行say_hello
self.hi_there = tk.Button(frame, text="hello", fg="green", command=self.say_hello)
self.hi_there.pack(side=tk.LEFT)
def say_hi(self):
print("Hello everyone!")
root = tk.Tk()
app = App(root)
root.mainloop()
通过上述例子可以看到发现,基本上所有tkinter设计的窗口,都要经过以下几个步骤:
基本上所有的组件创建,都遵循以下语法:
创建窗体——在窗体上创建组件
窗体变量 = Tk()
组件变量 = 组件名称(窗体变量 ,组件参数)
若要指定组件格式,需在创建组件变量时,通过参数进行修改。创建组件变量后无法修改
名称 | 含义 |
---|---|
Button | 按钮 |
Canvas | 绘图形组件,可以在其中绘制图形 |
Checkbutton | 复选框 |
Entry | 文本框(单行) |
Text | 文本框(多行) |
Frame | 框架,将几个组件组成一组 |
Label | 标签,可以显示文字或图片 |
Listbox | 列表框 |
Menu | 菜单 |
Menubutton | 它的功能完全可以使用Menu替代 |
Message | 与Label组件类似,但是可以根据自身大小将文本换行 |
for | 单选框 |
Scale | 滑块;允许通过滑块来设置一数字值 |
Scrollbar | 滚动条;配合使用canvas, entry, listbox, and text窗口部件的标准滚动条; |
Toplevel | 用来创建子窗口窗口组件 |
有些控件如Entry输入框、Checkbutton复选框、Radiobutton单选框等。有时希望将他们的值与一个变量绑定起来:若变量自身变化,将变化同步到组件值中;若组件中的值变化,将变化同步到变量中。
如刚说的三种组件,给其中的参数 variable 或 textvariable 赋值,就需要用到Tkinter自带的 Variable 类方可实现变量绑定。
Variable类下主要有4种子类,分别对应文本型、整型、浮点型、布尔型变量:
参数 | 含义 |
---|---|
StringVar() | 保存一个 string 类型变量, 默认值为"" |
IntVar() | 保存一个整型变量, 默认值为0 |
DoubleVar() | 保存一个浮点型变量, 默认值为0.0 |
BooleanVar() | 保存一个布尔型变量, 返回值为 0 (代表 False) 或 1 (代表 True) |
对变量的值进行读写主要通过两种方法:get()、set()
在使用时,可以先将变量实例化,然后赋值给组件类,实现变量绑定。在给组件赋值后,通过get()获取变量值。
如:
from tkinter import *
root= Tk()
v1 = StringVar() #创建String型变量
Entry = Entry(root,textvariable=v1) #将变量与Entry组件绑定
Entry.pack(padx=5,pady=5)
root.mainloop()
print(v1.get()) #将输出的内容打印
运行结果如下:
修改一下代码,看看set()是如何运行的:
from tkinter import *
root= Tk()
v1 = StringVar() #创建string型变量
v1.set('hello') #给变量赋初始值
Entry = Entry(root,textvariable=v1) #将变量与Entry组件绑定
Entry.pack(padx=5,pady=5)
root.mainloop()
运行结果如下:
接着,我们尝试给v1赋值为数值123,看看会不会出现什么不一样的地方:
from tkinter import *
root= Tk()
v1 = StringVar()
v1.set(123)
Entry = Entry(root,textvariable=v1)
Entry.pack(padx=5,pady=5)
root.mainloop()
print(v1.get()+1)
运行结果如下:
窗体显示并没有什么问题,能够显示123。但是关闭窗体后,将123与1相加,出现了 TypeError 异常:
我们将1修改为字符串,得到结果1231:
所以,我们可以得出一个结论:对于文本型变量,即使赋值为数值,仍然会转化为文本型
那么我们对整型变量赋值为数值会出现什么情况?修改代码如下:
from tkinter import *
root= Tk()
v1 = IntVar()
v1.set('123')
Entry = Entry(root,textvariable=v1)
Entry.pack(padx=5,pady=5)
root.mainloop()
print(v1.get()+1) #输出结果:124
可以发现,如果我们输入的是文本型数值,仍然能自动转化为整型。但是当我们输入的不是数值型文本时,会出现什么情况?
from tkinter import *
root= Tk()
v1 = IntVar()
v1.set('hello')
Entry = Entry(root,textvariable=v1)
Entry.pack(padx=5,pady=5)
root.mainloop()
print(v1.get())
运行截图如下:
即使是赋值为纯文本值,也不会出现异常。那么关闭窗体,执行调用v1的代码,结果如下
_tkinter.TclError: expected floating-point number but got "hello"
很显然,此时获取v1的值时,出现了_tkinter.TclError异常,告诉我们赋值为文本是错误的。
由此,我们可以得出如下结论
除了LabelFrame组件有12个参数: ‘e’、‘s’、‘w’、‘n’、‘es’、‘ws’、‘en’、‘wn’、‘ne’、‘nw’、‘se’、‘sw’ 等十二个方位
其他的组件anchor都只有:W,S,E,N,WS,WN,ES,EN,CENTER(默认)九个方位
设置字体,可以是
pack的布局原则是:按添加顺序排列组件。相比于grid,pack更适合少量组件的排列。通常来说,尽量不要在同一个父组件中混合使用grid和pack。
基本语法为:
组件.pack(anchor, expand, fill, ipadx, ipady, padx, pady, side)
参数含义
示例:将一个组件放到另一个组件中,并填满
from tkinter import *
root = Tk()
listbox = Listbox(root)
listbox.pack(fill=BOTH, expand=True)
for i in range(10):
listbox.insert(END, str(i))
mainloop()
结果如下:
fill 会告诉管理器,该组件将填充整个分配给他的空间,BOTH表示同时纵向横向,X表示横向,Y表示纵向;expand选项是告诉窗口管理器将父组件的额外空间也填满。
默认情况下,pack是将添加的组件依次纵向排列,可通过更改side改变排列方向
grid管理器,相当于一个表格,将组件放入表格中,形成一个规范的表格布局。在使用grid排列组件时,只需要传递(row 行,column 列)参数即可。此外,使用grid并不需要指明表格的尺寸,管理器会自动计算。
示例:创建一个带头像的登陆器
from tkinter import *
root = Tk()
Label(root, text="用户名").grid(row=0, sticky=W)
Label(root, text="密码").grid(row=1, sticky=W)
Entry(root).grid(row=0, column=1)
Entry(root, show="*").grid(row=1, column=1)
photo = PhotoImage(file="image/18.gif")
Label(root, image=photo).grid(row=0, column=2, rowspan=2, padx=5, pady=5)
Button(text="提交", width=10).grid(row=2, columnspan=3, pady=5)
mainloop()
运行如下:
默认情况下,grid 会将组件居中显示在网格中,若需要修改方向,可以设置sticky参数来更改。sticky参数值 与组件的 anchor 参数一样,为WSEN及其组合的方位。
如果要实现合并单元格(多网格放一个组件)的操作,设置rowspan和columnspan即可(见上例)
place 是通过指定相对于父组件的相对位置,来实现布局的。由于不同的组件可能尺寸不一等,要让组件对齐相当麻烦,因此在布局上不如前两个管理器。但是 place 可以实现覆盖布局。如果用坐标系来解释的话:pack 是在x 或y 轴上排列,grid 则是在xy坐标系中排列,而place则是在xyz坐标系中排列。
示例:创建一个RGB三色的矩形重叠形状
from tkinter import *
root = Tk()
Label(root, bg="red").place(relx=0.5, rely=0.5, relheight=0.75, relwidth=0.75, anchor=CENTER)
Label(root, bg="green").place(relx=0.5, rely=0.5, relheight=0.5, relwidth=0.5, anchor=CENTER)
Label(root, bg="blue").place(relx=0.5, rely=0.5, relheight=0.25, relwidth=0.25, anchor=CENTER)
mainloop()
运行如下:
在示例中,可以看到5个参数 relx、rely、relwidth、relheight、anchor,分别表示 相对于父组件的x位置、y位置、宽度、高度及方位。前四个参数都是以父对象为基准参考的,值都在0.0~1.0中,表示相对于父组件的位置及尺寸。如要显示在父组件中间,则令relx、rely为0.5,要有父组件四分之一大,则relheight及width为0.5
用于在界面上输出描述的标签,可以是文字,也可以是图片
参数 | 含义 |
---|---|
Anchor | 标签中文本的位置 |
background(bg) | 背景色 |
foreground(fg) | 前景色 |
borderwidth(bd) | 边框宽度 |
width | 标签宽度 |
height | 标签高度 |
bitmap | 标签中的位图 |
font | 字体 |
compound | 文本和图像的混合模式 |
image | 标签中的图片 |
justify | 多行文本的对齐方式 |
text | 标签中的文本,可以使用’\n’表示换行 |
textvariable | 显示文本自动更新,与StringVar等配合着用 |
示例:创建一个纯文字标签
from tkinter import *
root= Tk()
label = Label(root,text="hello")
label.pack()
root.mainloop()
用于创建一个按钮,除了设置按钮格式外,可以给按钮指定一个单击时触发的函数或方法
参数 | 含义 |
---|---|
anchor: | 指定按钮上文本的位置 |
background(bg) | 指定按钮的背景色 |
bitmap | 指定按钮上显示的位图 |
borderwidth(bd) | 指定按钮边框的宽度 |
command: | 指定按钮消息的回调函数 |
cursor: | 指定鼠标移动到按钮上的指针样式 |
font: | 指定按钮上文本的字体 |
foreground(fg) | 指定按钮的前景色 |
height: | 指定按钮的高度 |
image: | 指定按钮上显示的图片 |
state: | 指定按钮的状态(disabled) |
text: | 指定按钮上显示的文本 |
width: | 指定按钮的宽度 |
padx | 设置文本与按钮边框x的距离,还有pady |
activeforeground | 按下时前景色 |
textvariable | 可变文本,与StringVar等配合着用 |
Radiobotton为常见的单选框,根据是否选中,返回0、1
Checkbutton为常见的多选框,根据是否选中,返回0、1
参数 | 含义 |
---|---|
text | 显示文本内容 |
command | 指定Radiobutton的事件处理函数 |
image | 可以使用gif图像,图像的加载方法img = PhotoImage(root,file = filepath) |
bitmap | 指定位图,如bitmap= BitmapImage(file = filepath) |
value | 指定同一组的单选框的值 |
variable | 控制变量,跟踪Radiobutton的状态,On(1),Off(0) |
master | 代表了父窗口 |
bg | 背景色,如bg=”red”, bg="#FF56EF" |
fg | 前景色,如fg=”red”, fg="#FF56EF" |
font | 字体及大小,如font=(“Arial”, 8),font=(“Helvetica 16 bold italic”) |
height | 设置显示高度、如果未设置此项,其大小以适应内容标签 |
relief | 指定外观装饰边界附近的标签,默认是平的,可以设置的参数:flat、groove、raised、ridge、solid、sunken |
width | 设置显示宽度,如果未设置此项,其大小以适应内容标签 |
wraplength | 将此选项设置为所需的数量限制每行的字符,数默认为0 |
state | 设置组件状态;正常(normal),激活(active),禁用(disabled) |
selectcolor | 设置选中区的颜色 |
selectimage | 设置选中区的图像,选中时会出现 |
underline | With the default value of -1, none of the characters of the text label are underlined. Set this option to the inde |
bd | 设置Radiobutton的边框大小;bd(bordwidth)缺省为1或2个像素 |
textvariable | 设置Radiobutton的textvariable属性,文本内容变量 |
padx | 标签水平方向的边距, 默认为1像素 |
pady | 标签竖直方向的边距, 默认为1像素. |
justify | 标签文字的对齐方向, 可选值为 RIGHT, CENTER, LEFT, 默认为 CENTER |
与常规的Frame框架不同,LabelFrame框架带有Label标签,该标签可以是文字也可以是GUI组件。是Frame的升级版,可以让组件分组更加简洁直观
参数 | 含义 |
---|---|
bg | The normal background color displayed behind the label and indicator. |
bd | The size of the border around the indicator. Default is 2 pixels. |
cursor | If you set this option to a cursor name (arrow, dot etc.), the mouse cursor will change to that pattern when it is over the checkbutton. |
font | The vertical dimension of the new frame. |
height | The vertical dimension of the new frame. |
labelAnchor | 设置标签的位置。该选项支持 ‘e’、‘s’、‘w’、‘n’、‘es’、‘ws’、‘en’、‘wn’、‘ne’、‘nw’、‘se’、‘sw’ 这 12 个边项值,用于控制标签的位置。 |
highlightbackground | Color of the focus highlight when the frame does not have focus. |
highlightcolor | Color shown in the focus highlight when the frame has the focus. |
highlightthickness | Thickness of the focus highlight. |
relief | With the default value, relief=FLAT, the checkbutton does not stand out from its background. You may set this option to any of the other styles |
text | Specifies a string to be displayed inside the widget. |
width | Specifies the desired width for the window. |
用于输入信息,如用户名密码等。
参数 | 含义 |
---|---|
background(bg) | 文本框背景色; |
foreground(fg) | 前景色; |
selectbackground | 选定文本背景色; |
selectforeground | 选定文本前景色; |
borderwidth(bd) | 文本框边框宽度; |
font | 字体; |
show | 文本框显示的字符,若为*,表示文本框为密码框; |
state | 状态; |
width | 文本框宽度 |
textvariable | 可变文本,与StringVar等配合着用 |
validate | 设置验证类型 |
validatecommand | 指定一个验证函数,函数返回值为Bool |
invalidatecommand | 当validatecommand返回False时调用 |
获取组件中的内容,可以设置variable类变量,也可以直接使用get()方法
插入内容使用 insert() 方法,删除内容使用 delete() 方法。
如删除所有内容:Entry.delete(0,END)
插入指定文本:Entry.insert(0,"指定文本")
示例:创建一个登录框
from tkinter import *
root = Tk()
root.title("示例")
Label(root,text="用户名").grid(row=0)
Label(root,text="密码").grid(row=1)
e1 = Entry(root)
e2 = Entry(root,show="*")
e1.grid(row=0,column=1,padx=10,pady=5)
e2.grid(row=1,column=1,padx=10,pady=5)
def extract():
print('用户名:',e1.get())
print('密码:',e2.get())
e1.delete(0,END)
e2.delete(0,END)
Button(root,text="登录",width=10,command=extract).grid(row=3,column=0,padx=10,pady=5,sticky=W) #sticky表示位置
Button(root,text="退出",width=10,command=root.quit).grid(row=3,column=1,padx=10,pady=5,sticky=E)
mainloop()
运行如下:
除了基本的输入信息之外,Entry组件还支持验证功能,用于判断输入内容是否“合法”
首先需要设置validate参数,作为开启验证功能的开关。可设置的值如下:
值 | 含义 |
---|---|
focus |
当 Entry 组件获得或失去焦点的时候验证 |
focusin | 当 Entry 组件获得焦点的时候验证 |
focusout | 当 Entry 组件失去焦点的时候验证 |
key | 当输入框被编辑的时候验证 |
all | 当上面任何一种情况出现时验证 |
none | 关闭验证功能(默认值),注:是字符串 none 而不是None |
其次设置 validatecommand 参数,指定一个返回值为True 或 False 的验证函数
最后,当 validatecommand 指定的函数返回 False 时,触发 invalidatecommand 参数指定的返回值为bool类型的函数
示例:创建一个验证框,用户名为 admin 时输出“名称合法”,否则“请重新输入”
from tkinter import *
def func1():
if e1.get() == "admin":
print('名称合法')
return True
else:
return False
def func2():
print("请重新输入")
e1.delete(0,END)
return True
root = Tk()
root.title("示例")
Label(root,text="用户名").grid(row=0)
Label(root,text="密码").grid(row=1)
#当用户框失去焦点时验证
e1 = Entry(root,validate="focusout",validatecommand=func1,invalidcommand=func2)
e2 = Entry(root,show="*")
e1.grid(row=0,column=1,padx=10,pady=5)
e2.grid(row=1,column=1,padx=10,pady=5)
mainloop()
运行如下:
若设置为key,需要单次输入符合条件的内容,否则无法输入
使用验证功能时,还可以设置一些额外参数:
参数 | 含义 |
---|---|
%d | 操作代码:0 表示删除操作;1 表示插入操作;2 表示获得、失去焦点或textvariabel值被修改 |
%i | 当用户尝试插入或删除操作时,该参数表示插入或删除的位置(索引号),如果是因为获得、失去焦点或 textvariable 值被修改而调用验证函数,那么值为 -1 |
%P | 当输入框的值允许改变的时候,该值有效。该值为输入框的最新文本内容 |
%s | 该值为调用验证函数前输入框的文本内容 |
%S | 当插入或删除操作触发验证函数的时候,该值有效。该参数表示文本被插入和删除的内容 |
%v | 该组件当前的 validte 参数的值 |
%V |
调用验证函数的原因,该值是“focusin”,“focusout”,“key”或“forced”(textvriable 参数值被修改)中的一个 |
%W | 该组件的名字 |
使用这些额外参数前,需要先使用register()方法将验证函数包装,再将包装后的验证函数和额外参数组合为元组传递
以上面的例子为例,修改一下:
from tkinter import *
def func1(act,index,content,old_content,validate,reason,name):
if e1.get() == "admin":
print('名称合法')
print(act,index,content,old_content,validate,reason,name)
return True
else:
print('请重新输入')
print(act,index,content,old_content,validate,reason,name)
return False
root = Tk()
root.title("示例")
Label(root,text="用户名").grid(row=0)
Label(root,text="密码").grid(row=1)
test = root.register(func1)
e1 = Entry(root,validate="focusout",validatecommand=(test,"%d","%i",'%P','%s','%v','%V','%W'))
e2 = Entry(root,show="*")
e1.grid(row=0,column=1,padx=10,pady=5)
e2.grid(row=1,column=1,padx=10,pady=5)
mainloop()
运行如下:
调用验证函数,输出结果为:
名称合法
-1 -1 admin admin focusout focusout .!entry
当页面空间有限,而选项比较多时,使用列表框来存放诸多选项是比较好的选择
参数 | 含义 |
---|---|
master | 代表了父窗口 |
bg | 背景色,如bg=”red”, bg="#FF56EF" |
fg | 前景色,如fg=”red”, fg="#FF56EF" |
height | 设置显示高度、如果未设置此项,其大小以适应内容标签 |
relief | 指定外观装饰边界附近的标签,默认是平的,可以设置的参数:flat、groove、raised、ridge、solid、sunken |
width | 设置显示宽度,如果未设置此项,其大小以适应内容标签 |
state | 设置组件状态;正常(normal),激活(active),禁用(disabled) |
bd | 设置Button的边框大小;bd(bordwidth)缺省为1或2个像素 |
selectmode | 选择模式: SINGLE(单选) ROWSE(可通过鼠标或方向键改变的单选) MULTIPLE(多选) EXTENDED(可通过shift和ctrl配合使用,或鼠标拖动进行的多选) |
listvariable | 设置listvariable属性 |
创建Listbox时,内容为空,需要手动添加内容。若内容较多,应使用循环添加
示例:创建一个单击按钮删除选项的 Listbox:
from tkinter import *
root = Tk()
# 创建一个空列表
theLB = Listbox(root, setgrid=True)
theLB.pack()
# 往列表里添加数据
for item in ["钢铁侠", "蜘蛛侠", "绿灯侠", "神奇女侠"]:
theLB.insert(END, item)
theButton = Button(root, text="删除", command=lambda x=theLB: x.delete(ACTIVE))
theButton.pack()
mainloop()
但是有一个问题:Listbox 默认显示数量为10条,如果有超过10条的记录,该如何操作呢?
有两个方法:修改Listbox的height选项;添加Scrollbar 滚动条
Scrollbar 滚动条虽然是一个单独组件,但是通常配合其他组件一起使用,起到辅助显示内容的作用
若要为某个组件安装垂直滚动条,需要以下两步:
参数 | 含义 |
---|---|
master | 代表了父窗口 |
bg | 背景色,如bg=”red”, bg="#FF56EF" |
relief | 指定外观装饰边界附近的标签,默认是平的,可以设置的参数:flat、groove、raised、ridge、solid、sunken |
width | 设置显示宽度,如果未设置此项,其大小以适应内容标签 |
bd | 设置Button的边框大小;bd(bordwidth)缺省为1或2个像素 |
示例:创建一个带有滚动条的Listbox
# p17_19.py
from tkinter import *
root = Tk()
sb = Scrollbar(root)
sb.pack(side=RIGHT, fill=Y)
lb = Listbox(root, yscrollcommand=sb.set) #设置yscrollcommand选项为Scrollbar的set()方法
for i in range(1000):
lb.insert(END, str(i))
lb.pack(side=LEFT, fill=BOTH)
sb.config(command=lb.yview) #设置comand参数为组件的yview()方法
mainloop()
设置滚动条属性为组件的yview()方法,表示:当用户操作滚动条时,滚动条触发组件的yview()方法,使内容滚动
设置组件属性为set()方法的含义表示:内容的滚动会调用Scrollbar的set()方法,使滚动条滚动到相应位置
Scale与Scrollbar类似,但是不同的是,Scale是通过滑块表示某个范围的数值
参数 | 含义 |
---|---|
from_ | 设置该 Scale 的最小值(由于from是python关键字,故需要加下划线 from_) |
to | 设置该 Scale 的最大值 |
resolution | 设置该 Scale 滑动时的步长 |
label | 为 Scale 组件设置标签内容 |
length | 设置轨道的长度 |
width | 设置轨道的宽度 |
troughcolor | 设置轨道的背景色 |
sliderlength | 设置轨道的长度 |
sliderrelief | 设置滑块的立体样式 |
showvalue | 设置是否显示当前值 |
orient | 设置方向。该选项支持 VERTICAL 和 HORIZONTAL 两个值 |
digits | 设置有效数字至少要有几位 |
variable | 用于与变量进行绑定 |
command | 用于为该 Scale 组件绑定事件处理,函数或方法 |
示例:创建一个窗体,当单击按钮时,获取两个Scale组件的数值
from tkinter import *
root = Tk()
s1 = Scale(root, from_=0, to=42)
s1.pack()
s2 = Scale(root, from_=0, to=200, orient=HORIZONTAL)
s2.pack()
def show():
print(s1.get(), s2.get())
Button(root, text="获得位置", command=show).pack()
mainloop()
输出结果为:12 85
还可设置 resolution 控制分辨率(类似步长),设置 tickinterval 设置刻度
from tkinter import *
root = Tk()
#步长为5,刻度为5
Scale(root, from_=0, to=42, tickinterval=5, length=200, resolution=5, orient=VERTICAL).pack()
#步长为1,刻度为10
Scale(root, from_=0, to=200, tickinterval=10, length=600, orient=HORIZONTAL).pack()
mainloop()
Text 组件用于显示和处理多行文本,同样也可以作为简单的文本编辑器和网页浏览器
参数 | 含义 |
---|---|
background(bg) | 文本框背景色 |
foreground(fg) | 前景色 |
selectbackground | 选定文本背景色 |
selectforeground | 选定文本前景色 |
borderwidth(bd) | 文本框边框宽度 |
font | 字体 |
show | 文本框显示的字符,若为*,表示文本框为密码框 |
state | 状态 |
width | 文本框宽度 |
textvariable | 可变文本,与StringVar等配合着用 |
text 组件与 Entry 组件类似,创建时也是没有内容的,需要通过insert()方法来插入内容。而除了常规的文字内容外, text还可以插入window组件或者image图像
示例:
from tkinter import *
root = Tk()
text = Text(root, width=20, height=5)
text.pack()
text.insert(INSERT, "Hello everyone")
b1 = Button(text, text="ok")
text.window_create(INSERT, window=b1)
mainloop()
若需要在末尾创建图像,则使用 text.image_create(END , image=image)
Indexes表示索引,主要用于定位。Tkinter也提供了一系列的索引类型
表示第 line 行第 column 列,中间用”.“分隔行号列号,字符串或者浮点型都可识别。如”1.6“、2.5分别表示第1行第6列,第2行第5列。
需要注意的是:行号从1开始,列号从0开始,且若设置的行列号超过实际行列号,并不会报错,而是认为”已有内容末尾的下一个位置“
表示该行最后一个字符。如获取第一行第2至最后一个字符:text.get(”1.2“,"1.end")
插入光标的位置
与鼠标坐标最接近的位置(若长按任一按钮,直到松开时才会响应)
text文本缓冲区的最后一个位置的下一个位置
用户自定义的marks(marks见后文)
用户自定义的tags(tag见后文)
是一个特殊的tag,表示当前被选中的范围,可用SEL_FIRST、SEL_LAST表示该范围,若未选中内容,则抛出TclError异常
使用窗口坐标作为索引,如在事件绑定中,可通过以下代码找到最接近鼠标的位置:
"@%d,%d" % (event.x,event.y)
用于指向在Text组件中嵌入的window和image对象
要引用一个window,只要简单地将一个Tkinter组件实例作为索引即可。
引用一个嵌入的image,只需使用相应的PhotoImage和BitmapImage对象
expression
用于修改任何格式的索引,是用字符串的形式实现修改索引的表达式。具体如下:
表达式 | 含义 |
---|---|
”+ count chars" | 将索引向前(右)移动count个字符。可以越过换行符,但是不能超过END的位置 |
”- count chars" | 将索引向后(左)移动count个字符。可以越过换行符,但是不能超过"1.0"的位置 |
”+ count lines" | 将索引向前(右)移动count行。索引会尽量保持与移动前在同一列,若移动后的行字符不够前一行,则移动至行尾 |
”- count lines" | 将索引向后(左)移动count行。索引会尽量保持与移动前在同一列,若移动后的行字符不够前一行,则移动至行尾 |
" linestarrt" | 将索引移动至当前索引行的行首。注:使用该表达式前需有一个空格隔开 |
" lineend | 将索引移动至当前索引行的行尾。注:使用该表达式前需有一个空格隔开 |
" wordstart" | 将索引移动到当前索引指向的单词的开头。单词的定义是:一系列字母、数字、下划线或任意非空白字符的组合。注:使用该表达式前需有一个空格隔开 |
" wordend" | 将索引移动到当前索引指向的单词的结尾。单词的定义是:一系列字母、数字、下划线或任意非空白字符的组合。注:使用该表达式前需有一个空格隔开 |
只要结果不产生歧义,可以缩写关键字及省略空格,如”+ 5 chars"可以简写为"+5c"
示例:删除光标前一个字符
def backspace(event):
event.widget.delete("%s-1c" % INSERT,INSERT)
Mark(标记)通常是嵌入到Text组件中的不可见对象。text 默认包含3中marks:INSERT、CURRENT、user-defined marks
其中INSERT用于指定当前插入光标的位置,会绘制一个闪烁的光标(因此并非mark都不可见)
如果需在一个Mark前插入或删除文本,Mark会跟着一起移动。创建Mark需使用 mark_set()方法,删除Mark周围字符不会影响Mark
示例:插入语句“hello everyone”,将两个l中间的位置创建名为split的mark,并在该mark处插入空格
from tkinter import *
root = Tk()
text = Text(root, width=20, height=5)
text.pack()
text.insert(INSERT, "Hello everyone")
text.mark_set("split","1.3")
text.insert("split"," ")
mainloop()
运行如下:
删除自定义的Mark可使用mark_unset()方法,如删除上述的split标记 :text.mark_unset("split")
Tag(标签),通常用于改变Text组件中内容的样式和功能,可用来修改文本的字体、尺寸和颜色。另外,Tag 还允许将文本、嵌入的组件和图片与键盘和鼠标等事件相关联。
除了用户自定义的Tag,Tkinter还预设了一个特殊的Tag: SEL
创建Tag使用tag_add方法
示例:创建一个Tag1,内容为He、every,并设置为黄底蓝字
from tkinter import *
root = Tk()
text = Text(root, width=30, height=5)
text.pack()
text.insert(INSERT, "Hello everyone")
text.tag_add("tag1", "1.0", "1.2", "1.6","1.11")
text.tag_config("tag1", background="yellow", foreground="blue")
mainloop()
运行如下:
使用tag_config()方法可以设置Tag的样式,关于tag_config()方法的参数,在此不一一列举
若对同一个文本添加多个Tag,新的Tag会覆盖旧的Tag,可以使用tag_raise()、lower()方法提升或降低Tag的优先级。
如降低名为 split 的tag的优先级:text.tag_lower("split")
除了修改格式,Tag还可以进行事件绑定。绑定事件时使用tag_bind()方法
示例:当鼠标进入every文本段时,鼠标样式切换为“arrow”形态,离开时切换回“xtrem”
from tkinter import *
root = Tk()
text = Text(root, width=30, height=5)
text.pack()
text.insert(INSERT, "Hello everyone")
text.tag_add("tag1", "1.6", "1.11")
text.tag_config("tag1", foreground="red")
def show_hand_cursor(event):
text.config(cursor="arrow")
def show_arrow_cursor(event):
text.config(cursor="xterm")#xterm
text.tag_bind("tag1", "", show_hand_cursor)
text.tag_bind("tag1", "", show_arrow_cursor)
mainloop()
运行如下:
(1)判断内容是否变化
如关闭时判断内容是否进行修改,若修改则提醒。可通过Text组件中文本的MD5来判断内容是否变化。
使用MD5时,需要导入 hashlib 模块,再将文本内容传入
示例:创建一个getSig函数,获取文本的MD5值
import hashlib
def getSig(content):
m = hashlib.md5(content)
return m.digest()
(2)查找内容
使用search()方法可以搜索Text组件中的内容,可以提供一个确切的目标进行搜索(默认),也可以使用Tcl格式的正则表达式进行搜索(需设置 regexp 选项为True)。如在全文中查找目标文本:pos = text.search("目标文本",start,stopindex=END)
如果忽略stopindex选项,表示到末尾,若设置backwords为True,表示修改搜索方向为向后搜索。此时start应为END
(3)撤销、恢复操作
使用text.undo()表示撤销
使用text.redp()表示恢复
撤销和恢复只能处理一次“操作”,那么什么样的算一次“操作”呢?
默认操作:焦点切换、按下回车键、删除/插入操作的转换
那么,自定义“插入一个字符”算一个操作,使用撤销/恢复时操作也是处理一个字符。那么需要绑定键盘事件,在事件触发时,插入一个“分隔符”表示分隔操作。插入分隔符,可使用edit_separator()方法
示例:
from tkinter import *
root = Tk()
text = Text(root, width=30, height=5, autoseparators=False, undo=True, maxundo=10)
text.pack()
def callback(event):
text.edit_separator()
text.bind('', callback)
text.insert(INSERT, "Hello everyone")
def show():
text.edit_undo()
Button(root, text="撤销", command=show).pack()
mainloop()
运行如下:
Canvas 通常用于显示和绘制图形,可以通过它回值直线、圆形、多边形甚至是其他组件
参数 | 含义 |
---|---|
background(bg) | 背景色 |
foreground(fg) | 前景色 |
borderwidth | 组件边框宽度 |
width | 组件宽度 |
height | 高度 |
bitmap | 位图 |
image | 图片 |
在Canvas组件上绘制对象,可以用create_xxx()方法(xxx表示对象类型,如直线line,矩形rectangle,文本text等)
示例:创建一个蓝色的矩形:
from tkinter import *
root = Tk()
w = Canvas(root, width=200, height=100)
w.pack()
w.create_rectangle(50, 25, 150, 75, fill="blue")
mainloop()
运行如下:
绘制矩形时,4个位置参数分别表示:左上角点的x、左上角点的y、右下角点的x、右下角点的y。
那么,绘制一个圆形呢?这时就需要用到create_oval()
from tkinter import *
root = Tk()
w = Canvas(root, width=200, height=100)
w.pack()
w.create_oval(70,20,130,80)
mainloop()
运行如下:可以发现,绘制一个圆也是指定左上角右下角的点坐标。通过更改坐标可以绘制任意形状的圆、椭圆
那么,绘制一个多边形,则需要使用create_polygon(),以绘制一个国旗上的五角星为例:
from tkinter import *
import math as m
root = Tk()
w = Canvas(root, width=200, height=100, background="red")
w.pack()
center_x = 100
center_y = 50
r = 50
points = [
# 左上点
center_x - int(r * m.sin(2 * m.pi / 5)),
center_y - int(r * m.cos(2 * m.pi / 5)),
# 右上点
center_x + int(r * m.sin(2 * m.pi / 5)),
center_y - int(r * m.cos(2 * m.pi / 5)),
# 左下点
center_x - int(r * m.sin(m.pi / 5)),
center_y + int(r * m.cos(m.pi / 5)),
# 顶点
center_x,
center_y - r,
# 右下点
center_x + int(r * m.sin(m.pi / 5)),
center_y + int(r * m.cos(m.pi / 5)),
]
w.create_polygon(points, outline="yellow", fill="yellow")
mainloop()
运行如下:
由于五角星涉及三角函数,故需要导入math模块。
由此,可以发现:向Canvas传递位置参数时,可以是一个一个参数,也可以是由参数组成的列表或者元组。参数分别表示第一个点的xy,第二个点的xy……
既然存在画布工具,那么可不可以做到鼠绘呢?很显然,不能,因为Tkinter并没有提供自由画点的方法。所以只能偷天换日——画一个极小的圆代替点。此时,为了获取鼠标轨迹,就需要绑定事件了:
from tkinter import *
root = Tk()
w = Canvas(root, width=400, height=200)
w.pack()
def paint(event): #获取鼠标在组件内移动的x,y
x1, y1 = (event.x - 1), (event.y - 1)
x2, y2 = (event.x + 1), (event.y + 1)
w.create_oval(x1, y1, x2, y2, fill="black")
w.bind("", paint) #绑定事件:按住鼠标左键时在组件内移动的轨迹
Label(root, text="按住鼠标左键并移动即可开始自由绘制").pack(side=BOTTOM)
mainloop()
运行如下:
由于每次画点都是通过事件触发,每次事件触发的时间间隔基本固定,因此绘制的图像类似于打点计时器绘制的图像,速度快的地方点少,速度慢的地方点多。
其中,弦、扇形、椭圆形、圆形、多边形和矩形这些“封闭式”图形都是由轮廓线和填充颜色组成,可通过outline和fill选项设置他们的颜色,还可以设置为透明(传入空字符)
由于画布可能比窗口大(带有滚动条),因此Canvas组件可以选择使用两种坐标系:
窗口坐标系:以窗口的左上角为坐标原点
画布坐标系:以画布的左上角为坐标原点
在画布中创建的画布对象都会被列入显示列表中,下方的图形越接近背景。这一点有点像PS中的图层,新创建的图像会显示在旧图像的上层,在图层关系中也是上层。当然,组件中的显示列表也和图层一样,可以被重新排序
Canvas组件提供几种方法来指定画布对象
Item handles是一个用于指定某个画布对象的整型数(也称画布对象的ID)。当在Canvas组件上创建一个画布对象的时候,Tkinter将自动为其指定一个在Canvas中独一无二的整型值,然后各种Canvas方法可以通过这个值操纵该画布对象。
Tag是附在画布对象上的标签,Tag由普通的非空白字符串组成。一个画布对象可以与多个Tag相关联,一个Tag也可以用于描述多个画布对象。然而,与Text组件不同,没有指定画布对象的tag不能进行事件绑定和配置样式。即Canvas组件的Tag仅为画布对象所有。
Canvas预设了两个Tags:ALL和CURRENT
用于实现顶级菜单、下拉菜单和弹出菜单
函数 |
描述 |
---|---|
bg |
背景色,如bg=”red”, bg="#FF56EF" |
fg |
前景色,如fg=”red”, fg="#FF56EF" |
font |
字体及大小,如font=("Arial", 8),font=("Helvetica 16 bold italic") |
relief |
指定外观装饰边界附近的标签,默认是平的,可以设置的参数:flat、groove、raised、ridge、solid、sunken |
selectcolor |
设置选中区的颜色 |
bd |
设置Checkbutton的边框大小;bd(bordwidth)缺省为1或2个像素 |
创建顶级菜单时,创建的也是空白组件,需要通过add_command()方法添加顶级菜单。
而创建下拉菜单,需要先创建下拉菜单,再在将其绑定在顶级菜单中
如:创建开始、编辑菜单,下拉菜单中各有3个选项,第一个下拉菜单每个选项中添加一个分割线,第二个下拉菜单在与顶级菜单分界处创建横线分割线
from tkinter import *
root = Tk()
menubar = Menu(root)
# 创建一个下拉菜单“文件”,然后将它添加到顶级菜单中
filemenu = Menu(menubar, tearoff=False)
items=['打开','保存','另存为']
for item in items:
filemenu.add_command(label=item)
filemenu.add_separator()
menubar.add_cascade(label="开始", menu=filemenu)
# 创建另一个下拉菜单“编辑”,然后将它添加到顶级菜单中
editmenu = Menu(menubar, tearoff=True)
items = ['插入','删除','复制']
for item in items:
editmenu.add_command(label=item)
menubar.add_cascade(label="编辑", menu=editmenu)
# 显示菜单
root.config(menu=menubar)
运行如下:
在代码中实例化了两次Menu,还出现了不一样的代码。为了便于理解,绘制一个示意图,表示整个Menu的结构
第一次实例化创建的是一个空白导航栏,第二次实例化创建的是空白下拉菜单。对下拉菜单添加完按钮后,将其指定给导航栏的某个标签(同时创建该标签)。最后通过root.config()指定显示哪个导航栏(若创建了多个导航栏)。
示例:创建一个可切换的导航栏,单击第一个标签下拉菜单的【转换】按钮,切换至另一个导航栏
from tkinter import *
root = Tk()
root.title("First")
menubar = Menu(root)
menubar2 = Menu(root)
def call1():
root.title("First")
root.config(menu=menubar)
def call2():
root.title("Second")
root.config(menu=menubar2)
# 创建一个带转换按钮的导航栏
changemenu = Menu(menubar, tearoff=False)
item='转换'
changemenu.add_command(label=item,command=call2)
menubar.add_cascade(label="操作", menu=changemenu)
filemenu = Menu(menubar, tearoff=False)
items=['打开','保存','另存为']
for item in items:
filemenu.add_command(label=item)
menubar.add_cascade(label="文件", menu=filemenu)
editmenu = Menu(menubar, tearoff=False)
items = ['插入','删除','复制']
for item in items:
editmenu.add_command(label=item)
menubar.add_cascade(label="编辑", menu=editmenu)
changemenu = Menu(menubar2, tearoff=False)
item='转换'
changemenu.add_command(label=item,command=call1)
menubar2.add_cascade(label="操作", menu=changemenu)
othermenu = Menu(menubar2, tearoff=False)
items = ['帮助','升级','关于']
for item in items:
othermenu.add_command(label=item)
menubar2.add_cascade(label="其他", menu=othermenu)
# 显示菜单
root.config(menu=menubar)
mainloop()
运行如下:
除了向下拉菜单中添加自带选项之外,还可以添加单选、复选按钮。自带特殊函数如下:
函数 |
含义 |
---|---|
menu.add_cascade |
添加子选项 |
menu.add_command |
添加命令(label参数为显示内容) |
menu.add_separator |
添加分隔线 |
menu.add_checkbutton |
添加确认按钮 |
delete |
删除 |
该按钮可以在窗体其他位置创建菜单按钮,而不仅仅在顶级菜单中。创建方法与Menu的顶级菜单类似,代替了导航栏的位置。
示例:
from tkinter import *
root = Tk()
def callback():
print("~被调用了~")
mb = Menubutton(root, text="点我", relief=RAISED)
mb.pack()
filemenu = Menu(mb, tearoff=False)
filemenu.add_checkbutton(label="打开", command=callback, selectcolor="yellow")
filemenu.add_command(label="保存", command=callback)
filemenu.add_separator()
filemenu.add_command(label="退出", command=root.quit)
mb.config(menu = filemenu)
mainloop()
运行如下:
该组件是下拉菜单的改版,同样弥补了Listbox无法实现下拉列表框的缺陷。创建时需要创建一个Variable类变量,用于记录用户的选择。
示例:
from tkinter import *
root = Tk()
variable = StringVar()
variable.set("one")
w = OptionMenu(root, variable, "one", "two", "three")
w.pack()
mainloop()
print(variable.get())
运行如下:
若要获取用户的选择,对变量使用get()方法即可
该组件是Label的变体,用于显示多行文本,可以自动换行,并调整文本的尺寸使其适应给定的尺寸
示例:
from tkinter import *
root = Tk()
w1 = Message(root, text="下面插播一条新闻", width=100)
w1.pack()
w2 = Message(root, text="这条新闻超级的长长长长长长长长长长", width=100)
w2.pack()
mainloop()
该组件是TK8.4新增的组件,算是Entry的变体,类似于Scale与Entry组件的结合,使用时有点像Excel的数据有效性,用于从一些固定的值中选取一个。
Spinbox的用法与Entry非常相似,主要区别是Spinbox可以通过范围或者元组指定用户输入的内容
示例:创建一个男女信息框
from tkinter import *
root = Tk()
sb1=Spinbox(root,from_=0,to=1,value=("男","女"))
sb2=Spinbox(root,value=("男","女"))
sb1.pack()
sb2.pack()
mainloop()
运行如下:
若同时指定(from_,to)和value参数,如:
sb1=Spinbox(root,from_=0,to=1,value=("男","女"))
则value参数指定的范围会覆盖(from_,to)指定的范围
是TK8.4新增的组件,是一个空间管理器。与Frame类似,都是为组件提供一个框架,不过该组件允许用户调整程序的空间范围。
示例:创建一个PanedWindow组件,将空间分为两部分
from tkinter import *
m = PanedWindow(orient=VERTICAL)
m.pack(fill=BOTH, expand=1)
top = Label(m, text="top pane")
m.add(top)
bottom = Label(m, text="bottom pane")
m.add(bottom)
mainloop()
运行如下:
分割线默认是不显示的。可以设置sashrelief参数设置为SUNKEN,将showhandle参数设置为True则可以添加一个手柄(handle)
示例:添加横竖两个iPanedWindow组件,分隔空间为3部分,使分割线显示并添加手柄
from tkinter import *
m1 = PanedWindow(showhandle=True, sashrelief=SUNKEN)
m1.pack(fill=BOTH, expand=1)
left = Label(m1, text="left pane")
m1.add(left)
m2 = PanedWindow(orient=VERTICAL, showhandle=True, sashrelief=SUNKEN)
m1.add(m2)
top = Label(m2, text="top pane")
m2.add(top)
bottom = Label(m2, text="bottom pane")
m2.add(bottom)
mainloop()
运行如下:分隔三部分,可以先分为两部分,再添加一条线,分隔成三部分,如图
该组件类似于Frame组件,但是该组件有独立的标题栏、边框等部件,类似于弹窗,或者称子窗体。
主要用于显示额外的窗口、对话框和其他弹出窗口
示例:创建一个按钮,单击一次创建一个Toplevel 弹窗
from tkinter import *
root = Tk()
def create():
top = Toplevel()
top.title("示例")
msg = Label(top, text="这是一个Toplevel")
msg.pack()
Button(root, text="创建", command=create).pack()
mainloop()
运行如下:
若想获取和设置Toplevel的窗口属性,可以通过attributes()方法。若只设置属性名,则返回当前窗口该属性值;若设置属性名和值,则修改窗口的属性值
示例:将Toplevel的窗口设置为50%透明
from tkinter import *
root = Tk()
def create():
top = Toplevel()
top.title("示例")
top.attributes("-alpha", 0.5)
msg = Message(top, text="这是一个Toplevel")
msg.pack()
Button(root, text="创建Toplevel", command=create).pack()
mainloop()
事件,是执行某一操作时触发的事情。如:人饿的时候吃饭会饱,吃饭是操作,执行吃饭的操作时,饥饿感和饱腹感都在不断变化,相当于“吃饭”操作触发了“修改人的饥饿感属性和饱腹感属性”的事件。
一个Tkinter程序大部分事件都花在事件循环中(通过maxinloop()方法进入循环)。事件可以有各种来源,包括用户触发的鼠标、键盘操作和窗口管理器触发的重绘事件(绝大多数情况下都是由用户间接引起的)。
Tkinter提供一个强大的机制可以自由地处理事件:对每个组件来说,可通过bind()方法将函数或方法绑定到具体的事件上。当被处罚的事件满足该组件绑定的事件时,Tkinter就会带着事件描述去调用handler()方法。
示例:捕获键盘敲击位置
from tkinter import *
root = Tk()
def callback(event):
print("敲击位置:", repr(event.char))
frame = Frame(root, width=200, height=200)
frame.bind("", callback)
frame.focus_set() #使组件获得焦点
frame.pack()
mainloop()
运行如下:
注:键盘事件需要组件获得焦点才能接收,故需要用focus_set()方法使组件获得焦点
根据上述示例,可以大致归纳出绑定事件的基本步骤:
Tkinter可以使用事件序列的机制来自定义事件,只需要用bind()方法将具体的事件序列与自定义的方法绑定即可。
事件序列以字符串的形式表示,可以表示一个或多个相关联的事件(若为多个事件,需要满足所有事件条件才会调用)。
事件序列的语法为:
语法示例:
type关键词 |
含义 |
---|---|
Activate |
当组件的状态从“未激活”变为“激活”的时候触发事件 |
Button |
当用户单击鼠标按键时触发事件。detail部分指定具体哪个按键: |
ButtonRelease |
当用户释放鼠标按键的时候触发事件。在大多数情况下,比Button更好用,因为当用户不小心按下鼠标,用户可以将鼠标移出组件再释放鼠标,从而避免不小心触发事件 |
Configure |
当组件的尺寸发生改变的时候触发事件 |
Deactivate |
当组建的状态从“激活”变为“未激活的时候触发事件 |
Destroy |
当组件被小伙的时候触发事件 |
Enter |
当鼠标指针进入组件的时候触发事件。注意:不是指用户按下回车键 |
Expose |
当窗口或组件的某部分不再被覆盖的时候触发事件 |
FocusIn |
当组件获得焦点的时候触发事件。用户可以用Tab键将焦点转移到该组件上(需要该组件的takefocus选项为True);也可以调用focus_set()方法使该组件获得焦点 |
FocusOut |
当组件失去焦点的时候触发事件 |
KeyPress |
当用户按下键盘按键的时候触发事件。detail可以指定具体的按键,例如 |
KeyRElease |
当用户释放键盘按键的时候触发事件 |
Leave |
当鼠标指针离开组件的时候触发事件 |
Map |
当组件被映射的时候触发事件。意思是在应用程序中显示该组件的时候触发事件,例如调用grid()方法 |
Motion |
当鼠标在组件内移动的整个过程均触发事件 |
MouseWheel |
当鼠标滚轮滚动的时候触发事件。目前仅支持Windows和Mac系统,Linux请参考Button |
Unmap |
当组件被取消映射的时候触发事件。指在应用成组中不再显示该组件的时候触发事件,例如调用grid_remove()方法 |
Visibility |
当应用程序至少有一部分在屏幕中是可见的时候触发事件 |
关键词 |
含义 |
---|---|
Alt |
当按下Alt按键的时候触发事件 |
Any |
表示任何类型的按键被按下的时候触发事件。例如 |
Control |
当按下Ctrl按键的时候触发事件 |
Double |
当后续两个事件被连续触发的时候触发事件。例如 |
Lock |
当打开大写字母锁定键(CapsLock)的时候触发按键 |
Shift |
当按下Shift按键的时候触发事件 |
Triple |
与Double类似,当后续三个事件被连续触发的时候触发事件 |
当Tkinter回调预先定义的函数时,将带着Event对象(作为参数)去调用。
属性 |
含义 |
---|---|
widget |
产生该事件的组件 |
x, y |
当前的鼠标位置坐标(相对于窗口左上角,以像素为单位) |
x_root, y_root |
当前的鼠标位置坐标(相对于屏幕左上角,以像素为单位) |
char |
按键对应的字符(键盘事件专属) |
keysym |
按键名(键盘事件专属) |
keycode |
按键码(键盘事件专属) |
num |
按钮数字(鼠标事件专属) |
width, height |
组件的新尺寸(Configure 事件专属)) |
type |
该事件的类型 |
当事件为
按键名(keysym) |
按键码(keycode) |
含义 |
---|---|---|
Alt_L |
64 |
左边的 Alt 键 |
Alt_R |
113 |
右边的 Alt 键 |
BackSpace |
22 |
BackSpace(退格)键 |
Cancel |
110 |
break 键 |
Caps_Lock |
66 |
CapsLock |
Control_L |
37 |
左边的 Ctrl 键 |
Control_R |
109 |
右边的 Ctrl 键 |
Delete |
107 |
Delete 键 |
Down |
104 |
↓ 键 |
End |
103 |
End 键 |
Escape |
9 |
Esc 键 |
Execute |
111 |
SysReq键 |
F1 |
67 |
F1 键 |
F2 |
68 |
F2 键 |
F3 |
69 |
F3 键 |
F4 |
70 |
F4 键 |
F5 |
71 |
F5 键 |
F6 |
72 |
F6 键 |
F7 |
73 |
F7 键 |
F8 |
74 |
F8 键 |
F9 |
75 |
F9 键 |
F10 |
76 |
F10 键 |
F11 |
77 |
F11 键 |
F12 |
96 |
F12 键 |
Home |
97 |
Home 键 |
Insert |
106 |
Insert 键 |
Left |
100 |
←键 |
Linefeed |
54 |
Linefeed(Ctrl+J) |
KP |
90 |
小键盘 0 |
KP_1 |
87 |
小键盘 1 |
KP_2 |
88 |
小键盘 2 |
KP_3 |
89 |
小键盘 3 |
KP_4 |
83 |
小键盘 4 |
KP_5 |
84 |
小键盘 5 |
KP_6 |
85 |
小键盘 6 |
KP_7 |
79 |
小键盘 7 |
KP_8 |
80 |
小键盘 8 |
KP_9 |
81 |
小键盘 9 |
KP_Add |
86 |
小键盘 + |
KP_Begin |
84 |
小键盘 中间键(5) |
KP_Decimal |
91 |
小键盘 . |
KP_Delete |
91 |
小键盘 Delete |
KP_Divide |
112 |
小键盘 / |
KP_Down |
88 |
小键盘 ↓ |
KP_End |
87 |
小键盘 End |
KP_Enter |
108 |
小键盘 Enter |
KP_Home |
79 |
小键盘 Home |
KP_Insert |
90 |
小键盘 Insert |
KP_Left |
83 |
小键盘 ← |
KP_Multiply |
63 |
小键盘 * |
KP_Next |
89 |
小键盘 PaageDown |
KP_Prior |
81 |
小键盘 PageUp |
KP_Right |
85 |
小键盘 → |
KP_Subtract |
82 |
小键盘 - |
KP_Up |
80 |
小键盘 ↑ |
Next |
105 |
PageDwon 键 |
Num_Lock |
77 |
Num_Lock(数字锁定) 键 |
Pause |
110 |
Pause(暂停) 键 |
|
111 |
PrintScm(打印屏幕) 键 |
Prior |
99 |
PAgeUP 键 |
Return |
36 |
Enter(回车)键 |
Right |
102 |
→ 键 |
Scroll_Lock |
78 |
Scroll_Lock 键 |
Shift_L |
50 |
左边的 Shift 键 |
Shift_R |
62 |
右边的 Shift 键 |
Tab |
23 |
Tab 键 |
Up |
98 |
↑键 |
使用函数 |
对话框样式 |
---|---|
askokcancle() |
|
askquestion() |
|
askretrycancel() |
|
askyesno() |
|
showerror() |
|
showinfo() |
|
showwarning() |
所有函数都有相同的参数:title、message、options
title:设置标题栏的文本内容
message设置对话框的主要文本内容,可以用’\n’来实现换行
options参数设置内容见下表
options选项
含义
default
设置默认的按钮(直接回车时相应的按钮),默认是第一个按钮
icon
指定对话框显示的图标,可以是error、INFO、QUESTION、WARNING。但是不能是自己的图标
parent
如果不指定该选项,那么对话框默认显示在根窗口上
如果想要将对话框显示在子窗口w上,设置parnet=w
关于parent需要注意的是:如果未指定parent参数,也未创建一个任何一个窗体,使用上述函数
生成messagebox时,会自动创建一个空白的Tk窗体,产生的效果与实例化Tk()相同。空白Tk窗体如下:
而如果parent参数设置的是Tk类下的子窗体,如Toplevel,则会创建两个空白tk窗体,一个表示Tk窗体,一个表示Toplevel窗体。运行如下:
窗体间的结构大致如下:
若关闭Toplevel,则会同时关闭messagebox;若关闭Tk,则会将Toplevel、messagebox一同关闭,因为他们都是基于Tk创建的子窗体。
但是,当直接关闭Tk时,会出现AttributeError: 'NoneType' object has no attribute 'tk'异常;关闭Toplevel再关闭Tk或从messagebox开始从上往下关闭,则不会出现该异常。
askokcancel()、askretrycancel()和askyesno()返回bool类型值:
askquestion()返回yes或no字符串表示用户单击了“是”或:否“按钮
showerror(),showinfo()或showwarning()返回ok表示用户按下了“是“按钮
示例:打开文件,并获取路径
from tkinter import *
import tkinter.filedialog
root = Tk()
def callback():
fileName = tkinter.filedialog.askopenfilename()
print(fileName)
Button(root, text="打开文件", command=callback).pack()
mainloop()
运行如下:
注:若没有import tkinter.filedialog 语句,则会出现错误:NameError: name 'filedialog' is not defined
filedialog模块提供以下函数
函数
含义
askopenfile()
生成打开单个文件的对话框,返回所选择文件的文件流
askopenfiles()
生成打开多个文件的对话框,返回多个所选择文件的文件流组成的列表
askopenfilename()
生成打开单个文件的对话框,返回所选择文件的文件路径
askopenfilenames()
生成打开多个文件的对话框,返回多个所选择文件的文件路径组成的元组
asksaveasfile()
生成保
运行如下:
注:若没有import tkinter.filedialog 语句,则会出现错误:NameError: name 'filedialog' is not defined
filedialog模块提供以下函数:
函数 |
含义 |
askopenfile() |
生成打开单个文件的对话框,返回所选择文件的文件流 |
askopenfiles() |
生成打开多个文件的对话框,返回多个所选择文件的文件流组成的列表 |
askopenfilename() |
生成打开单个文件的对话框,返回所选择文件的文件路径 |
askopenfilenames() |
生成打开多个文件的对话框,返回多个所选择文件的文件路径组成的元组 |
asksaveasfile() |
生成保存文件的对话框,返回所选择文件的文件输出流 |
asksaveasfilename() |
生成保存文件的对话框,返回所选择文件的文件路径 |
askdirectory() |
生成打开目录的对话框 |
两个函数可供设置的参数是一样的,参数如下
参数 |
含义 |
defaultextension |
指定文件的后缀,例如defaultextension=“.jpg“,当用户输入一个文件名是,会自动添加.jpg后缀 注:若输入的文件名包含后缀,则该选项不生效 |
filetypes |
指定筛选文件类型的下拉菜单选项,该选项的值是由2元组构成的列表。每个2元组由(类型名,后缀名)构成,如:filetypes=[(“PNG”,”.png”),(“JPG”,”.jpg”)] |
initialdir |
指定打开/保存文件的默认路径,默认路径是当前文件夹 |
initialfile |
指定所选择的文件 |
parent |
如果不指定该选项,那么对话框默认显示在根窗口上 如果想要将对话框显示在子窗口w上,设置parent=w |
title |
指定文件对话框的标题栏文本 |
multiple |
指定是否允许多选 |
对于打开目录的对话框,还额外支持一个 mustexist 选项,该选项指定是否只允许打开己存在的目录
返回值
的对话框,返回所选择文件的文件输出流
asksaveasfilename()
生成保存文件的对话框,返回所选择文件的文件路径
askdirectory()
生成打开目录的对话框
这些函数可供设置的参数基本上是一样的,参数如下
参数
含义
defaultextension
指定文件的后缀,例如defaultextension=“.jpg“,当用户输入一个文件名是,会自动添加.jpg后缀
注:若输入的文件名包含后缀,则该选项不生效
filetypes
指定筛选文件类型的下拉菜单选项,该选项的值是由2元组构成的列表。每个2元组由(类型名,后缀名)构成,如:filetypes=[(“PNG”,”.png”),(“JPG”,”.jpg”)]
initialdir
指定打开/保存文件的默认路径,默认路径是当前文件夹
initialfile
指定所选择的文件
parent
如果不指定该选项,那么对话框默认显示在根窗口上
如果想要将对话框显示在子窗口w上,设置parent=w
title
指定文件对话框的标题栏文本
multiple
指定是否允许多选
注:对于打开目录的对话框,还额外支持一个 mustexist 选项,该选项指定是否只允许打开己存在的目录