import tkinter # 导入 Tkinter 模块
win = tkinter.Tk() # 创建 Windows 窗口对象
win.title('我的第一个 GUI 程序') # 设置窗口标题
win.geometry("800x600") # 设置串口大小
#win.minsize(400, 600) # (选用)
#win.maxsize(1440, 800)
win.mainloop() # 进入消息循环,也就是显示窗口
geometry()
方法,格式如下:宽度x高度 (注:x是小写字母x,不是乘号)
minsize()
方法设置窗口的最小尺寸,使用maxsize()
方法设置窗口的最大尺寸,方法如下:窗口对象.minsize(最小宽度, 最大宽度)
窗口对象.maxsize(最小高度, 最大高度)
Tkinter 几何布局管理器(Geometry Manager)用于组织和管理父组件(往往是窗口)中子组件的布局方式。Tkinter 提供了 3 种不同风格的几何布局管理类,即pack
、grid
和place
。
pack 几何布局管理器采用块的方式组织组件,pack 布局根据子组件创建生成的顺序将其放在快速生成的界面中。
调用子组件的方法pack()
,则该子组件在其父组件中采用 pack 布局:
pack(option=value, ...)
pack()
方法提供了如下表所示的若干参数选项。
选项 | 描述 | 取值范围 |
---|---|---|
side | 停靠在父组件的哪一边上 | ‘top’(默认值)、‘bottom’、‘left’、‘right’ |
anchor | 停靠位置,对应于东、南、西、北以及4个角 | ‘n’、‘s’、‘e’、‘w’、‘nw’、‘sw’、‘se’、‘ne’、‘center’(默认值) |
fill | 填充空间 | ‘x’、‘y’、‘both’、‘none’ |
expand | 扩展空间 | 0或1 |
ipadx、ipady | 组件内部在x/y方向上填充的空间大小 | 单位为c(厘米)、m(毫米)、i(英寸)、p(打印机的点) |
padx、pady | 组件外部在x/y方向上填充的空间大小 | 单位为c(厘米)、m(毫米)、i(英寸)、p(打印机的点) |
import tkinter
root = tkinter.Tk()
root.geometry("400x300")
label = tkinter.Label(root, text='hello, python')
label.pack() # 将Label组件添加到窗口中显示
button1 = tkinter.Button(root, text='BUTTON1')
# 创建文字是“BUTTON1”的Button组件
button1.pack(side=tkinter.LEFT)
# 将button1组件添加到窗口中显示,左停靠
button2 = tkinter.Button(root, text='BUTTON2')
# 创建文字是“BUTTON2”的Button组件
button2.pack(side=tkinter.RIGHT)
# 将button2组件添加到窗口中显示,右停靠
root.mainloop()
grid 几何布局管理器采用表格结构组织组件。 子组件的位置由行/列确定的单元格决定,子组件可以跨越多行/列。在每一列中,列宽由这一列中最宽的单元格确定。grid 几何布局管理器适合表现表格形式的布局,可以实现复杂的界面,因而被广泛使用。
调用子组件的grid()
方法,则该子组件在其父组件中采用 grid 几何布局:
grid(option=value, ...)
grid()
方法提供了如下表所示的若干参数选项。
选项 | 描述 | 取值范围 |
---|---|---|
sticky | 组件津贴所在单元格的某一边角,对应于东、南、西、北以及4个角 | ‘n’、‘s’、‘e’、‘w’、‘nw’、‘sw’、‘se’、‘ne’、‘center’(默认值) |
row | 单元格行号 | 整数 |
column | 单元格列号 | 整数 |
rowspan | 行跨度 | 整数 |
columnspan | 列跨度 | 整数 |
ipadx、ipady | 组件内部在x/y方向上填充的空间大小 | 单位为c(厘米)、m(毫米)、i(英寸)、p(打印机的点) |
padx、pady | 组件外部在x/y方向上填充的空间大小 | 单位为c(厘米)、m(毫米)、i(英寸)、p(打印机的点) |
from tkinter import *
root = Tk()
# 200x200代表了初始化是主窗口的大小,280和280代表了
# 初始化时窗口所在的位置
root.geometry('200x200+280+280')
root.title('计算器示例')
# grid(网格)布局
L1 = Button(root, text='1', width=5, bg='yellow')
L2 = Button(root, text='2', width=5)
L3 = Button(root, text='3', width=5)
L4 = Button(root, text='4', width=5)
L5 = Button(root, text='5', width=5, bg='green')
L6 = Button(root, text='6', width=5)
L7 = Button(root, text='7', width=5)
L8 = Button(root, text='8', width=5)
L9 = Button(root, text='9', width=5, bg='yellow')
L0 = Button(root, text='0')
Lp = Button(root, text='.')
L1.grid(row=0, column=0) # 按钮放置在0行0列
L2.grid(row=0, column=1) # 按钮放置在0行1列
L3.grid(row=0, column=2) # 按钮放置在0行2列
L4.grid(row=1, column=0) # 按钮放置在1行0列
L5.grid(row=1, column=1) # 按钮放置在1行1列
L6.grid(row=1, column=2) # 按钮放置在1行2列
L7.grid(row=2, column=0) # 按钮放置在2行0列
L8.grid(row=2, column=1) # 按钮放置在2行1列
L9.grid(row=2, column=2) # 按钮放置在2行2列
L0.grid(row=3, column=0, columnspan=2,
sticky=E+W) # 跨两行,左右贴紧
Lp.grid(row=3, column=2,
sticky=E+W) # 左右贴紧
root.mainloop()
place 几何布局管理器允许指定组件的大小和位置。place 几何布局管理器的优点是可以精确地控制组件的位置,不足之处是改变窗口大小时子组件不能随之灵活地改变大小。
调用子组件的方法place()
,则该子组件在其父组件中采用 place 布局:
place(option=value, ...)
place()
方法提供了如下表所示的若干参数选项,用户可以直接给参数选项赋值加以修改。
选项 | 描述 | 取值范围 |
---|---|---|
x,y | 将组件放到指定位置的绝对坐标 | 从0开始的整数 |
relx,rely | 将组件放到指定位置的相对坐标 | 0~1.0 |
height,width | 高度和宽度,单位为像素 | |
anchor | 对齐方式,对应于东、南、西、北以及4个角 | ‘n’、‘s’、‘e’、‘w’、‘nw’、‘sw’、‘se’、‘ne’、‘center’(默认值) |
注意
Python 的坐标系是左上角为原点位置(0,0),向右是 x 坐标正方向,向下是 y 坐标正方向。
place 几何布局管理器的 GUI 示例程序如下所示:
from tkinter import *
root = Tk()
root.title("登录")
root['width'] = 200; root['height'] = 80
Label(root, text='用户名', width=6).place(x=1, y=1)
# 绝对坐标(1, 1)
Entry(root, width=20).place(x=45, y=1)
# 绝对坐标(45, 1)
Label(root, text='密码', width=6).place(x=1, y=20)
# 绝对坐标(1, 20)
Entry(root, width=20, show='*').place(x=45, y=20)
# 绝对坐标(45, 20)
Button(root, text='登录', width=8).place(x=40, y=40)
# 绝对坐标(40, 40)
Button(root, text='取消', width=8).place(x=110, y=40)
# 绝对坐标(110, 40)
root.mainloop()
Tkinter 提供了很多组件,例如按钮、标签和文本框等,在一个 GUI 应用程序中使用,这些组件通常被称为控件或者部件。Tkinter 组件如下表所示:
控件 | 描述 |
---|---|
Button | 按钮控件,在程序中显示按钮 |
Canvas | 画布控件,显示图形元素,例如线条或文本 |
Checkbutton | 多选框控件,用于在程序中提供多项选择框 |
Entry | 输入控件,用于显示简单的文本内容 |
Frame | 框架控件,在屏幕上显示一个矩形区域,多用来作为容器 |
Label | 标签控件,可以显示文本和位图 |
Listbox | 列表框控件,用来显示一个字符串列表给用户 |
Menubutton | 菜单按钮控件,用于显示菜单项 |
Menu | 菜单控件,显示菜单栏、下拉菜单和弹出菜单 |
Message | 消息控件,用来显示多行文本,与Label比较类似 |
Radiobutton | 单选按钮控件,显示一个单选的按钮状态 |
Scale | 范围控件,显示一个数值刻度,为输出限定范围的数字区间 |
Scrollbar | 滚动条控件,在内容超过可视化区域时使用,例如列表框 |
Text | 文本控件,用于显示多行文本 |
Toplevel | 容器控件,用来提供一个单独的对话框,和Frame比较类似 |
Spinbox | 输入控件,与Entry类似,但是可以指定输入范围值 |
PanedWindow | PanedWindow是一个窗口布局管理的插件,可以包含一个或者多个子控件 |
LabelFrame | LabelFrame是一个简单的容器控件,常用语复杂的窗口布局 |
tkMessageBox | 用于显示应用程序的消息框 |
from tkinter import *
root = Tk()
button1 = Button(root, text="确定")
组件的标准属性也就是所有组件(控件)的共同属性,例如大小、字体和颜色等。Tkinter 组件常用的标准属性如下表所示。
属性 | 描述 |
---|---|
dimension | 控件大小 |
color | 颜色 |
font | 控件字体 |
anchor | 锚点(内容停靠位置),对应于东、南、西、北以及4个角 |
relief | 控件样式 |
bitmap | 位图,内置位图包括error、gray75、gray50、gray25、gray12、info、questhead、hourglass、question和warning,自定义位图为.xbm格式的文件 |
curson | 光标 |
text | 显示文本内容 |
state | 设置组件状态为正常(normal)、激活(active)或禁用(disabled) |
button1 = Button(root, text="确定“) #按钮组件的构造函数
button1.config(text="确定") #组件对象的config()方法的命名参数
button1["text"] = "确定" #组件对象的属性的赋值
Label 组件用于在窗口中显示文本或位图。
例如,
from tkinter import *
win = Tk() # 创建窗口对象
win.title("我的窗口") # 设置窗口标题
lab1 = Label(win, text='你好', anchor='nw')
# 创建文字是“你好”的Label组件
lab1.pack() # 显示Label组件
# 显示内置的位图
lab2 = Label(win, bitmap='question')
# 创建显示疑问图标Label组件
lab2.pack() # 显示Label组件
# 显示自选的图片
bm = PhotoImage(file=r'D:\Projects\Python3_TEST\Setting.png')
lab3 = Label(win, image=bm)
lab3.bm = bm
lab3.pack() # 显示Label组件
win.mainloop()
Button 组件(控件)是一个标准的 Tkinter 部件,用于实现各种按钮。按钮可以包含文本或图像,可以通过 command属性将调用函数或方法关联到按钮上。当 Tkinter 的按钮被按下时会自动调用该函数或方法。
Entry 组件主要用于输入单行内容和显示文本,可以方便地向程序传递用户参数。
Entry 对象 = Entry(Windows 窗口对象)
Entry 对象.pack()
get()
方法用于获取单行文本框内输入的内容。StringVar()
对象来完成,把 Entry 的 textvariable 属性设置为StringVar()
变量,再通过StringVar()
变量的get()
和set()
函数读取和输出相应文本内容。s = StringVar() # 一个StringVar()对象
s.set("大家好,这是测试")
entryCd = Entry(root, textvariable=s)
# Entry组件显示“大家好,这是测试”
print(s.get()) # 打印出“大家好,这是测试”
列表框组件 Listbox用于显示多个项目,并且允许用户选择一个或多个项目。
Listbox 对象 = Listbox(Tkinter Windows 窗口对象)
Listbox 对象.pack()
insert()
方法向列表框组件中插入文本项,方法如下:Listbox 对象.insert(index, item)
其中,index 是插入文本项的位置,如果在尾部插入文本项,则可使用 END;如果在当前选中插入文本项,则可使用 ACTIVE。item 是要插入的文本项。
Listbox 对象.curselection()
返回当前选中项目的索引,结果为元组。索引号从 0 开始,0 表示第 1 项。
Listbox 对象.delete(first, last)
删除指定范围 first~last 的项目,当不指定 last 时删除 1 个项目。
Listbox 对象.get(first, last)
返回指定范围 first~last 的项目,当不指定 last 时仅返回 1 个项目。
Listbox 对象.size()
m = StringVar()
listb = Listbox(root, listvariable=m)
listb.pack()
root.mainloop()
指定后就可以使用m.get()
方法获取 Listbox 对象中的内容了。
注意
如果允许用户选择多个项目,需要将 Listbox 对象的 selectmode 属性设置为 MULTIPLE(表示多选),而设置为SINGLE表示单选。
示例:创建一个列表框选择内容添加到另一个列表框的 GUI 程序。
from tkinter import * # 导入Tkinter库
root = Tk() # 创建窗口对象
def callbutton1():
for i in listb.curselection(): # 遍历选中项
listb2.insert(0, listb.get(i)) # 添加到右侧列表框
def callbutton2():
for i in listb2.curselection(): # 遍历选中项
listb2.delete(i) # 从右侧列表框中删除
# 创建两个列表
li = ['C', 'python', 'php', 'html', 'SQL', 'java']
listb = Listbox(root) # 创建两个列表框组件
listb2 = Listbox(root)
for item in li: # 左侧列表框组件插入数据
listb.insert(0, item)
listb.grid(row=0, column=0, rowspan=2) # 将列表框组件放置到窗口对象中
b1 = Button(root, text='添加>>', command=callbutton1, width=20)
# 创建Button组件
b2 = Button(root, text='删除<<', comman=callbutton2, width=20)
# 创建Button组件
b1.grid(row=0, column=1, rowspan=2) # 显示Button组件
b2.grid(row=1, column=1, rowspan=2) # 显示Button组件
listb2.grid(row=0, column=2, rowspan=2)
root.mainloop() # 进入消息循环
单选按钮组件 Radiobutton 和复选框组件 Checkbutton 分别用于实现选项的单选和复选功能。
Radiobutton 用于从同一组单选按钮中选择一个单选按钮(不能同时选择多个)。Radiobutton 可以显示文本,也可以显示图像。
Checkbutton 用于选择一项或多项,同样 Checkbutton 可以显示文本,也可以显示图像。
Radiobutton 对象 = Radiobutton(Windows 窗口对象, text=Radiobutton 组件显示的文本)
Radiobutton 对象.pack()
用户可使用 variable 属性为 Radiobutton 组件指定一个对应的变量。如果将多个 Radiobutton 组件绑定到同一个变量,则这些 Radiobutton 组件输入一个分组。分组后需要使用 value 设置每个 Radiobutton 组件的值,以标识该项目是否被选中。
Checkbutton 对象 = Checkbutton(Tkinter Windows 窗口对象, text=Checkbutton 组件显示的文本, command=单击 Checkbutton 按钮所调用的回调函数)
Checkbutton 对象.pack()
c = tkinter.IntVar()
c.set(2)
check = tkinter.Checkbutton(root, text='喜欢', variable=c, onvalue=1, offvalue=2)
check.pack()
指定变量 c 后,可以使用c.get()
获取复选框的状态值,也可以使用c.set()
设置复选框的状态。
示例:创建使用单选按钮(Radiobutton)组件选择国家的程序。
import tkinter
root = tkinter.Tk()
r = tkinter.StringVar() # 创建StringVar对象
r.set('1') # 设置初始值为“1”,初始选中“中国”
radio = tkinter.Radiobutton(root, variable=r, value='1', text='中国')
radio.pack()
radio = tkinter.Radiobutton(root, variable=r, value='2', text='美国')
radio.pack()
radio = tkinter.Radiobutton(root, variable=r, value='3', text='日本')
radio.pack()
radio = tkinter.Radiobutton(root, variable=r, value='4', text='加拿大')
radio.pack()
radio = tkinter.Radiobutton(root, variable=r, value='5', text='韩国')
radio.pack()
root.mainloop()
print(r.get()) # 获取被选中单选按钮变量值
图形用户界面应用程序通常提供菜单,菜单包含各种按照主题分组的基本命令。通常,图形用户界面应用程序包括两种类型的菜单。
(1) 主菜单:提供窗体的菜单系统。通过单击可下拉出子菜单,选择命令可执行相关的操作。常用的主菜单一般包括文件、编辑、视图、帮助等。
(2) 上下文菜单(也称为快捷菜单):通过右击某对象而弹出的菜单,一般为与该对象相关的常用菜单命令,例如剪切、复制、粘贴等。
Menu 对象 = Menu(Windows 窗口对象)
Windows 窗口对象['menu'] = Menu 对象
Windows 窗口对象.mainloop()
示例:使用 Menu 组件的简单例子:
from tkinter import *
root = Tk()
def hello(): # 菜单项事件函数,每个菜单项可以单独写
print("你单击主菜单")
m = Menu(root)
for item in ['文件', '编辑', '视图']: # 添加菜单项
m.add_command(label=item, command=hello)
root['menu'] = m # 附加主菜单到窗口
root.mainloop()
消息窗口组件 Messagebox 用于弹出提示框向用户进行告警,或让用户选择下一步如何操作。
消息框包括很多类型,常用的有info、warning、error、yesno、okcancel等,包含不同的图标、按钮以及弹出提示音。
示例:演示各消息框的程序:
import tkinter as tk
from tkinter import messagebox as msgbox
def btn1_clicked():
msgbox.showinfo("Info", "Showinfo test.")
def btn2_clicked():
msgbox.showwarning("Warning", "Showwarning test.")
def btn3_clicked():
msgbox.showerror("Error", "Showerror test.")
def btn4_clicked():
msgbox.askquestion("Question", "Askquestion test.")
def btn5_clicked():
msgbox.askokcancel("OkCancel", "Askokcancel test.")
def btn6_clicked():
msgbox.askyesno("YesNo", "Askyesno test.")
def btn7_clicked():
msgbox.askretrycancel("Retry", "Askretrycancel test.")
root = tk.Tk()
root.title("MsgBox Test")
btn1 = tk.Button(root, text="showinfo", comman=btn1_clicked)
btn1.pack(fill=tk.X)
btn2 = tk.Button(root, text="showwarning", comman=btn2_clicked)
btn2.pack(fill=tk.X)
btn3 = tk.Button(root, text="showerror", comman=btn3_clicked)
btn3.pack(fill=tk.X)
btn4 = tk.Button(root, text="askquestion", comman=btn4_clicked)
btn4.pack(fill=tk.X)
btn5 = tk.Button(root, text="askokcancel", comman=btn5_clicked)
btn5.pack(fill=tk.X)
btn6 = tk.Button(root, text="askyesno", comman=btn6_clicked)
btn6.pack(fill=tk.X)
btn7 = tk.Button(root, text="askretrycancel", comman=btn7_clicked)
btn7.pack(fill=tk.X)
root.mainloop()
Frame 组件是框架组件,在分组组织其他组件的过程中是非常重要的,负责安排其他组件的位置。Frame 组件在屏幕上显示为一个矩形区域,作为显示其他组件的容器。
Frame 对象 = Frame(窗口对象, height=高度, width=宽度, bg=背景色, ...)
Frame 对象. pack()
Label(Frame 对象, text='Hello').pack() #向Frame组件中添加一个Label组件
LabelFrame(窗口对象, height=高度, width=宽度, text=标题).pack()
示例:使用两个 Frame 组件和一个 LabelFrame 组件的例子。
from tkinter import *
root = Tk() # 创建窗口对象
root.title("使用 Frame 组件的例子") # 设置窗口标题
f1 = Frame(root) # 创建第1个Frame组件
f1.pack()
f2 = Frame(root) # 创建第2个Frame组件
f2.pack()
f3 = LabelFrame(root, text='第 3 个 Frame')
# 第3个LabelFrame组件,放置在窗口底部
f3.pack(side=BOTTOM)
redbutton = Button(f1, text="Red", fg="red")
redbutton.pack(side=LEFT)
brownbutton = Button(f1, text="Brown", fg="brown")
brownbutton.pack(side=LEFT)
bluebutton = Button(f1, text="Blue", fg="blue")
bluebutton.pack(side=LEFT)
blackbutton = Button(f2, text="Black", fg="black")
blackbutton.pack()
greenbutton = Button(f3, text="Green", fg="Green")
greenbutton.pack()
root.mainloop()
after()
方法每隔几秒刷新 GUI 图形界面。from tkinter import *
colors = ('red', 'orange', 'yellow', 'green', 'blue', 'purple')
root = Tk()
f = Frame(root, height=200, width=200)
f.color = 0
f['bg'] = colors[f.color] # 设置框架背景色
lab1 = Label(f, text='0')
lab1.pack()
def foo():
f.color = (f.color+1) % (len(colors))
lab1['bg'] = colors[f.color]
lab1['text'] = str(int(lab1['text'])+1)
f.after(500, foo) # 隔500 ms执行foo()函数刷新屏幕
f.pack()
f.after(500, foo)
root.mainloop()
显示效果如下图所示:
示例:开发移动电子广告效果就可以使用after()
方法实现不断移动 lab1。
from tkinter import *
root = Tk()
f = Frame(root, height=200, width=200)
lab1 = Label(f, text='欢迎参观工学院')
x = 0
def foo():
global x
x += 10
if x > 200:
x = 0
lab1.place(x=x, y=0)
f.after(500, foo) # 隔500 ms执行foo()函数刷新屏幕
f.pack()
f.after(500, foo)
root.mainloop()
通过组件的 font 属性可以设置其显示文本的字体,注意在设置组件字体前首先要能表示一个字体。
通过 3 个元素的元组可以表示字体:
(font family, size, modifiers)
作为一个元组的第 1 个元素的 font family 是字体名;size 为字体大小,单位为 point;modifiers 包含粗体、斜体、下划线的样式修饰符。
例如:
("Times New Roman ", "16") # 16点阵的Times字体
("Times New Roman ", "24", "bold italic") # 24点阵的Times字体,且为粗体、斜体
示例:通过元组表示字体设置标签的字体。
from tkinter import *
root = Tk()
# 创建Label
for ft in ('Arial', ('Courier New', 19, 'italic'),
('Comic Sans MS',), 'Fixdsys', ('MS Sans Serif',)
, ('MS Serif',), 'Symbol', 'System',
('Times New Roman',), 'Verdana'):
Label(root, text='hello sticky', font=ft).grid()
root.mainloop()
使用 tkFont.Font 来创建字体,格式如下:
ft = tkFont.Font(family='字体名', size, weight,
salant, underline, overstrike)
其中,size 为字体大小;weight=‘bold’ 或 ‘normal’,‘bold’ 为粗体;slant=‘italic’ 或 ‘narmal’,‘italic’ 为斜体;underline=1 或 0, 1 为下划线;overstrike=1 或 0, 1为删除线。
ft = Font(fanily='Helvetica', size=36, weigth='bold')
示例:通过 Font 对象设置标签字体。
# 通过Font对象来创建字体
from tkinter import *
import tkinter.font
root = Tk()
# 指定字体名称、大小、样式
ft = tkinter.font.Font(family='Fixdsys', size=20,
weight='bold')
Label(root, text='hello sticky', font=ft).grid()
# 创建一个Label
root.mainloop()
运行效果如下图所示:
通过tkFont.families()
函数可以返回所有可用的字体。
from tkinter import *
import tkinter.font # 引入字体模块
root = Tk()
print(tkinter.font.families())
输出结果:
('System', '@System', 'Terminal', '@Terminal', 'Fixedsys', '@Fixedsys', 'Modern', 'Roman', 'Script', 'Courier', 'MS Serif', 'MS Sans Serif', 'Small Fonts', 'Adobe 黑体 Std R', '@Adobe 黑体 Std R', 'Adobe 明體 Std L', '@Adobe 明體 Std L', 'Adobe Myungjo Std M', '@Adobe Myungjo Std M', 'Adobe Pi Std', 'Adobe 宋体 Std L', '@Adobe 宋体 Std L', 'Courier Std', 'Kozuka Gothic Pr6N M', '@Kozuka Gothic Pr6N M', 'Kozuka Mincho Pr6N R', '@Kozuka Mincho Pr6N R', 'Myriad CAD', 'Mathcad UniMath Prime', 'Marlett', 'Arial', 'Arabic Transparent', 'Arial Baltic', 'Arial CE', 'Arial CYR', 'Arial Greek', 'Arial TUR', 'Arial Black', 'Bahnschrift Light', 'Bahnschrift SemiLight', 'Bahnschrift', 'Bahnschrift SemiBold', 'Bahnschrift Light SemiCondensed', 'Bahnschrift SemiLight SemiConde', 'Bahnschrift SemiCondensed', 'Bahnschrift SemiBold SemiConden', 'Bahnschrift Light Condensed', 'Bahnschrift SemiLight Condensed', 'Bahnschrift Condensed', 'Bahnschrift SemiBold Condensed', 'Calibri', 'Calibri Light', 'Cambria', 'Cambria Math', 'Candara', 'Comic Sans MS', 'Consolas', 'Constantia', 'Corbel', 'Courier New', 'Courier New Baltic', 'Courier New CE', 'Courier New CYR', 'Courier New Greek', 'Courier New TUR', 'Ebrima', 'Franklin Gothic Medium', 'Gabriola', 'Gadugi', 'Georgia', 'Impact', 'Ink Free', 'Javanese Text', 'Leelawadee UI', 'Leelawadee UI Semilight', 'Lucida Console', 'Lucida Sans Unicode', 'Malgun Gothic', '@Malgun Gothic', 'Malgun Gothic Semilight', '@Malgun Gothic Semilight', 'Microsoft Himalaya', 'Microsoft JhengHei', '@Microsoft JhengHei', 'Microsoft JhengHei UI', '@Microsoft JhengHei UI', 'Microsoft JhengHei Light', '@Microsoft JhengHei Light', 'Microsoft JhengHei UI Light', '@Microsoft JhengHei UI Light', 'Microsoft New Tai Lue', 'Microsoft PhagsPa', 'Microsoft Sans Serif', 'Microsoft Tai Le', '微软雅黑', '@微软雅黑', 'Microsoft YaHei UI', '@Microsoft YaHei UI', '微软雅黑 Light', '@微软雅黑 Light', 'Microsoft YaHei UI Light', '@Microsoft YaHei UI Light', 'Microsoft Yi Baiti', 'MingLiU-ExtB', '@MingLiU-ExtB', 'PMingLiU-ExtB', '@PMingLiU-ExtB', 'MingLiU_HKSCS-ExtB', '@MingLiU_HKSCS-ExtB', 'Mongolian Baiti', 'MS Gothic', '@MS Gothic', 'MS UI Gothic', '@MS UI Gothic', 'MS PGothic', '@MS PGothic', 'MV Boli', 'Myanmar Text', 'Nirmala UI', 'Nirmala UI Semilight', 'Palatino Linotype', 'Segoe MDL2 Assets', 'Segoe Print', 'Segoe Script', 'Segoe UI', 'Segoe UI Black', 'Segoe UI Emoji', 'Segoe UI Historic', 'Segoe UI Light', 'Segoe UI Semibold', 'Segoe UI Semilight', 'Segoe UI Symbol', '宋体', '@宋体', '新宋体', '@新宋体', 'SimSun-ExtB', '@SimSun-ExtB', 'Sitka Small', 'Sitka Text', 'Sitka Subheading', 'Sitka Heading', 'Sitka Display', 'Sitka Banner', 'Sylfaen', 'Symbol', 'Tahoma', 'Times New Roman', 'Times New Roman Baltic', 'Times New Roman CE', 'Times New Roman CYR', 'Times New Roman Greek', 'Times New Roman TUR', 'Trebuchet MS', 'Verdana', 'Webdings', 'Wingdings', 'Yu Gothic', '@Yu Gothic', 'Yu Gothic UI', '@Yu Gothic UI', 'Yu Gothic UI Semibold', '@Yu Gothic UI Semibold', 'Yu Gothic Light', '@Yu Gothic Light', 'Yu Gothic UI Light', '@Yu Gothic UI Light', 'Yu Gothic Medium', '@Yu Gothic Medium', 'Yu Gothic UI Semilight', '@Yu Gothic UI Semilight', '等线', '@等线', '等线 Light', '@等线 Light', '仿宋', '@仿宋', '楷体', '@楷体', '黑体', '@黑体', 'HoloLens MDL2 Assets', 'Meiryo', '@Meiryo', 'Meiryo UI', '@Meiryo UI', 'MS Mincho', '@MS Mincho', 'MS PMincho', '@MS PMincho', 'UD Digi Kyokasho N-B', '@UD Digi Kyokasho N-B', 'UD Digi Kyokasho NP-B', '@UD Digi Kyokasho NP-B', 'UD Digi Kyokasho NK-B', '@UD Digi Kyokasho NK-B', 'UD Digi Kyokasho N-R', '@UD Digi Kyokasho N-R', 'UD Digi Kyokasho NP-R', '@UD Digi Kyokasho NP-R', 'UD Digi Kyokasho NK-R', '@UD Digi Kyokasho NK-R', 'Yu Mincho', '@Yu Mincho', 'Yu Mincho Demibold', '@Yu Mincho Demibold', 'Yu Mincho Light', '@Yu Mincho Light', 'Book Antiqua', 'Century', 'Century Gothic', 'Leelawadee', 'Microsoft Uighur', 'Wingdings 2', 'Wingdings 3', '方正舒体', '@方正舒体', '方正姚体', '@方正姚体', '隶书', '@隶书', '幼圆', '@幼圆', '华文彩云', '@华文彩云', '华文仿宋', '@华文仿宋', '华文琥珀', '@华文琥珀', '华文楷体', '@华文楷体', '华文隶书', '@华文隶书', '华文宋体', '@华文宋体', '华文细黑', '@华文细黑', '华文行楷', '@华文行楷', '华文新魏', '@华文新魏', '华文中宋', '@华文中宋', 'MT Extra', 'Arvo', 'Droid Serif', 'Indie Flower', 'Lobster', 'Open Sans', 'Poiret One', 'Raleway', 'Roboto Condensed', 'Roboto Slab', '汉仪长仿宋体', '@汉仪长仿宋体', 'SWAstro', 'OLF SimpleSansOC', 'SWComp', 'SWGothe', 'SWGothg', 'SWGothi', 'SWGrekc', 'SWGreks', 'SWIsop1', 'SWIsop2', 'SWIsop3', 'SWIsot1', 'SWIsot2', 'SWIsot3', 'SWItal', 'SWItalc', 'SWItalt', 'SWMap', 'SWMath', 'SWMeteo', 'SWMono', 'SWMusic', 'SWRomnc', 'SWRomnd', 'SWRomns', 'SWRomnt', 'SWScrpc', 'SWScrps', 'SWSimp', 'SWTxt', 'SWGDT', 'SWLink', 'SOLIDWORKS GDT', 'INSPECTIONXPERT GDT FRAMES', 'INSPECTIONXPERT GDT NOFRMS', 'NX ANSI Symbols', 'NX Constraints', 'NX ISO Symbols', 'FontAwesome', 'icon-brand', 'Roboto', 'GLYPHICONS Halflings', 'icon-large', 'icon-small', 'icon-ui', 'Museo Sans For Dell')
程序可以使用事件处理函数来指定当触发某个时间时所做的反应(操作)。
事件类型的通用格式如下:
<[modifier-]···type[-detail]>
事件类型必须放置于尖括号<>内。 type 描述了类型,例如键盘按键、鼠标单击。modifier 用于组合键定义,例如 Control、Alt。detail 用于明确定义是哪一个键或按钮的事件,例如 1 表示鼠标左键、2 表示鼠标中键、3 表示鼠标右键。
举例如下:
<Button-1> # 按下鼠标左键
<KeyPress-A> # 按下键盘上的A键
<Control-Shift-KeyPress-A> # 同时按下了Control、Shift、A 3个键
Python 中的键盘事件如下:
名称 | 描述 |
---|---|
KeyPress | 按下键盘上的某键时触发,可以在detail部分指定是哪个键 |
KeyRelease | 释放键盘上的某键时触发,可以在detail部分指定是哪个键 |
Python 中的鼠标事件如下:
名称 | 描述 |
---|---|
ButtonPress或Button | 按下鼠标某键,可以在detail部分指定是哪个键 |
ButtonRelease | 释放鼠标某键,可以在detail部分指定是哪个键 |
Motion | 点中组件的同时拖曳组件移动时触发 |
Enter | 当鼠标指针移进某组件时触发 |
Leave | 当鼠标指针移出某组件时触发 |
MouseWheel | 当鼠标滚轮滚动时触发 |
Python 中的窗体事件如下:
名称 | 描述 |
---|---|
Visibility | 当组件变为可视状态时触发 |
Unmap | 当组件由显示状态变为隐藏状态时触发 |
Map | 当组件由隐藏状态变为显示状态时触发 |
Expose | 当组件从原本被其他组件遮盖的状态中暴露出来时触发 |
FocusIn | 当组件获得焦点时触发 |
FocusOut | 当组件失去焦点时触发 |
Configure | 当改变组件大小时触发,例如拖曳窗体边缘 |
Property | 当窗体的属性被删除或改变时触发,属于Tk的核心事件 |
Destroy | 当组件被销毁时触发 |
Activate | 与组件选项中的state项有关,表示组件由不可用转为可用,例如按钮由disabled(灰色)转为enabled |
Deactivate | 与组件选项中的state项有关,表示组件由可用转为不可用,例如按钮由enabled转为disabled(灰色) |
modifier 组合键定义中常用的修饰符见下表:
修饰符 | 描述 |
---|---|
Alt | Alt键按下 |
Any | 任何按键按下,例如 |
Control | Control键按下 |
Double | 两个事件在短时间内发生,例如双击鼠标左键 |
Lock | Caps Lock键按下 |
Shift | Shift键按下 |
Triple | 类似于Double,3个事件短时间内发生 |
可以用短格式表示事件,例如 <1> 等同于
、 等同于 。
对于大多数的单字符按键,用户还可以忽略 “ <> ” 符号,但是空格键和尖括号键不能这样做(正确的表示分别为、 )。
程序建立一个处理某一事件的事件处理函数称为绑定。
def callback(): # 事件处理函数
showinfo("Python comman", "人生苦短,我用Python")
Bu1 = Button(root, text="设置command事件调用命令", command=callback)
Bul.pack()
bind()
可以为指定组件实例绑定事件,这是最常用的事件绑定方式。组件对象实例名.bind("<事件类型>", 事件处理函数)
tag_bind()
。预先为图形定义标识 tag 后,通过标识 tag 来绑定事件。例如:cv.tag_bind('r1', '' , printRect)
示例:标识绑定的例子。
from tkinter import *
root = Tk()
def printRect(event):
print('rectangle左键事件')
def printRect2(event):
print('rectangle右键事件')
def printLine(event):
print('Line事件')
cv = Canvas(root, bg='white')
# 创建一个Canvas,设置其背景色为白色
rt1 = cv.create_rectangle(
10, 10, 110, 110,
width=8, tags='r1')
cv.tag_bind('r1', '' , printRect)
# 绑定item与鼠标左键事件
cv.tag_bind('r1', '' , printRect2)
# 绑定item与鼠标右键事件
# 创建一个line,并将其tags设置为'r2'
cv.create_line(180, 70, 280, 70, width=10, tags='r2')
cv.tag_bind('r2', '' , printLine)
# 绑定item与鼠标左键事件
cv.pack()
root.mainloop()
def callback(event): # 事件处理函数
showinfo("Python command", "人生苦短,我用Python")
Event 对象可以获取各种相关参数,主要参数如下表所示。
参数 | 说明 |
---|---|
.x,.y | 鼠标相对于组件对象左上角的坐标 |
.x_root,.y_root | 鼠标相对于屏幕左上角的坐标 |
.keysym | 字符串命名按键,例如Escape、F1~F12、Scroll_Lock、Pause、Insert、Delte、Home、Prior(这个是page up)、Next(这个是page down)、End、Up、Right、Left、Down、Shift_L、Shift_R、Control_L、Control_R、Alt_L、Alt_R、Win_L |
.keysym_num | 数字代码命名按键 |
.keycode | 键码,但是它不能反映事件前缀Alt、Control、Shift、Lock,并且它不区分大小写按键,即输入a和A是相同的键码 |
.time | 时间 |
.type | 事件类型 |
.widget | 触发事件的对应组件 |
.char | 字符 |
Event 对象按键的详细信息如下表所示:
.keysym | .keycode | .keysym_num | 说明 |
---|---|---|---|
Alt_L | 64 | 65513 | 左手边的Alt键 |
Alt_R | 113 | 65514 | 右手边的Alt键 |
BackSpace | 22 | 65288 | BackSpace键 |
Cancel | 110 | 65387 | Pause Break键 |
F1~F11 | 67~77 | 65470~65480 | 功能键F1~F11 |
111 | 65377 | 打印屏幕键 |
from tkinter import * # 导入Tkinter库
def printkey(event): # 定义的函数监听键盘事件
print('你按下了: ' + event.char)
root = Tk() # 实例化tk
entry = Entry(root) # 实例化一个单行输入框
# 给输入框绑定按键监听事件为监听任何按键
# 为监听某键x,例如为监听A、
# 为监听回车
entry.bind('' , printkey)
entry.pack()
root.mainloop() # 显示窗体
运行效果如下图所示:
示例:获取鼠标单击标签时坐标的鼠标事件例子。
from tkinter import * # 导入Tkinter库
def leftClick(event): # 定义的函数监听鼠标事件
print("x轴坐标:", event.x)
print("y轴坐标", event.y)
print("相对于屏幕左上角x轴坐标:", event.x_root)
print("相对于屏幕左上角y轴坐标:", event.y_root)
root = Tk() # 实例化tk
lab = Label(root, text="hello") # 实例化一个Label
lab.pack() # 显示Label组件
# 给Label绑定鼠标监听事件
lab.bind("" , leftClick)
root.mainloop() # 显示窗体