一个Tkinter应用程序大部分时间是花在事件循环当中的,也就是通过mainloop()进入的事件循环。
事件可以有各种来源:用户触发的鼠标和键盘操作和窗口管理器触发的重绘事件(在多数情况下是由用户简介引起的)
Tkinter给我们提供了一个强大的机制去管理这些事件,去定义这些事件的操作。对每一个组件来说,可以通过bind()的方法来将自己定义的函数或方法绑定到具体的事件上。
widget.bind(event, handler)
当被触发的事件满足该组件绑定的事件的时候,Tkinter就会带着事件对象(Event、事件本身的描述)去调用自定义的handler()方法。
捕获鼠标点击的位置的演示:
-
from tkinter import *
-
root =Tk()
-
#当触发<Button-1>,Tkinter会带着事件本身去调用callback,会把它传入到callback中,因此要个形参来接收对应的事件描述
-
def callback(event):
-
print("点击位置:", event.x, event.y) #这个x和y表示的是相对于应用程序左上角的x和y。root的x和y相对的是屏幕
-
frame = Frame(root, width=200, height=200)
-
frame.bind("<Button-1>", callback) # -左边是事件本身,右边是事件详细描述。Button表示的是鼠标的点击事件,1表示的是左键,2代表滚轮,3表示右键,4、5对于Linux系统才有用,表示滚轮向上滚和向下滚。对于Windows和Mac系统来说则是通过mousewhell来表示用户是向上滚还是向下滚了滚轮。
-
frame.pack()
-
mainloop()
关于键盘的演示:
-
from tkinter import *
-
root =Tk()
-
def callback(event):
-
print(event.char) #获取当前键盘按下的字符
-
frame = Frame(root, width=200, height=200)
-
frame.bind("<Key>", callback) #组件想要响应键盘事件,组件必须获得焦点,组件才会响应键盘来的消息。因为一个窗口可以有很多组件,键盘一次敲击不知道给哪个组件。
-
frame.focus_set() #通过focus_set方法获得焦点。也可以设置Frame的takefocus选项为True,然后使用Tab将焦点转移上来
-
frame.pack()
-
mainloop()
利用<Motion>事件获取鼠标实时位置的方式
-
from tkinter import *
-
root =Tk()
-
def callback(event):
-
print("当前位置:", event.x, event.y)
-
frame = Frame(root, width=200, height=200)
-
frame.bind("<Motion>", callback) #Motion事件表示当鼠标进入组件时,就会响应这个事件
-
frame.focus_set()
-
frame.pack()
-
mainloop()
下方主要内容:
1.事件序列
2.type
3.modifier
4.Event对象
5.Key names
事件序列:
Tkinter使用一种称为事件序列的机制来允许用户定义事件,用户需要使用bind()方法将具体的事件序列与自定义的方法相绑定。事件序列是以字符串的形式表示的,可以表示一个或多个相关联的事件(若果是多个事件,那么对应的方法只有在满足所有事件的前提下才会被调用)
事件序列使用以下语法描述:
<modifier-type-detail>
事件序列是包含在尖括号(<...>)中的
type部分的内容是必须的,它通常用于描述普通的事件类型,例如鼠标点击或键盘按键点击
modifier部分的内容是可选的,它通常用于描述组合键,例如Ctrl + c(<Control-Key-C>),Shift + 鼠标左键点击(<Shift-Button-1>)
detail部分的内容是可选的,它通常用于描述具体的按键,例如Button-1表示的是鼠标左键
如:
事件序列<Button-1>:用户点击鼠标左键
事件序列<KeyPress-H>:用户点击H按键
事件序列<Control-Shift-KeyPress-H>:用户同时点击Ctrl + Shift +H
type
type: Active:当组件的状态从“未激活”变为“激活”的时候触发该事件
Button:当用户点击鼠标按键的时候触发该事件
detail部分指定是具体用哪个键:<Button-1>鼠标左键,<Button-2>鼠标中键(滚轮点击),<Button-3>鼠标右键,<Button-4>滚轮上滚(Linux),<Button-5>滚轮下滚(Linux)
ButtonRelease:当用户释放鼠标按键的时候触发该事件
在大多数情况下,比Button要更好使用,因为如果当用户不小心按下鼠标键,用户可以将鼠标移出组件再释放鼠标,从而避免不小心触发事件
Configure:当组件的尺寸改变的时候触发该事件(窗口管理器触发的重绘事件,当你调整组件的尺寸或者移动应用程序,组件会和窗口一样被重绘)
Deactivate:当组件的状态从“激活”变为“未激活”的时候触发该事件
Destroy当组件被销毁时触发该事件
Enter:当鼠标指针进入组件的时候触发该事件
注意:不是用户按下回车键(回车键是Return<Key-Return>)
Expose:当窗口或组件的某部分不再被覆盖的时候触发该事件
FocusIn:当组件获得焦点的时候触发该事件
用户可以用Tab键将焦点转移到该组件上(需要该组件的takefocus选项为True)
你也可以调用focus_set()方法使该组件获得焦点
FocusOut:当组件失去焦点的时候触发该事件
KeyPress:当用户按下键盘按键的时候触发该事件
detail可以指定具体的按键,例如<KeyPress-H>表示当大写字母H被按下的时候触发该事件
KeyPress可以缩写为Key
KeyRelease:当用户释放键盘按键的时候触发该事件
Leave:当鼠标指针离开组件的时候触发该事件
Map:当组件被映射的时候触发该事件
意思是在应用程序中显示该组件的时候,例如调用get()方法
Motion:当鼠标在组件内移动的时候触发该事件
MouseWheel当鼠标滚轮滚动的时候触发该事件
目前该事件仅支持Windows和Mac系统
Unmap:当组件被取消映射的时候触发该事件
意思是在应用程序中不再显示该组件的时候,例如调用grid_remove()方法
Visibility:当应用程序至少有一部分在屏幕中是可见的时候触发该事件
modifier
在事件序列中,modifier部分的内容可以是以下这些:
Alt:当按下Alt按键的时候
Any:表示任何类型的按键被按下的时候
例如<Any-keyPress>表示当用户按下任何按键时触发事件
Control:当按下Ctrl按键的时候
Double:当后续两个事件被连续触发的时候
例如<Double-Button-1>表示当用户双击鼠标左键时触发事件
Lock:当打开大写字母锁定键(CapsLock)的时候
Shift:当按下Shift按键的时候
Triple:跟Double类似,当后续三个事件被连续触发的时候
Event对象:
当Tkinter去回调你定义的函数的时候,就会带着Event对象(作为参数)去调用,Event对象以下这些属性你可以使用:
widget:产生该事件的组件
x, y:当前的鼠标的位置坐标(相对于窗口左上角,单位为像素)
x_root, y_root:当前的鼠标的位置坐标(相对于屏幕左上角,单位为像素)
char:按键对应的字符(键盘事件专属,不会显示Control,Shift等键)
keysym:按键名,见下方Key names(键盘事件专属)
keycode:按键码,见下方Key names(键盘事件专属)
num:按钮数字(鼠标事件专属)
width, height:组件的新尺寸(Configure事件专属)
type:该事件类型
Key names
当事件为<Key>,<KeyPress>,<KeyRelease>的时候,detail可以通过设定具体的按键名(keysym)来筛选。例如<Key-H>表示按下键盘上的大写字母H时候触发事件,<Key-Tab>表示按下键盘上的Tab按键的时候触发事件。
下边列举了键盘所有特殊按键的keysym和keycode(按键码是对应美国标准101键盘的“Lantin-1”字符集,键盘标准不同,对应的按键码不同,但按键名是一样的)
-
按键名(keysym) 按键码(keycode) 代表的按键
-
Alt_L 64 左边的Alt按键
-
Alt_R 113 右边的Alt按键
-
BackSpace 22 BackSpace(退格)按键
-
Cancel 110 break按键
-
Caps_Lock 66 CapsLock(大写字母锁定)按键
-
Control_L 37 左边的Control
-
Control_R 109 右边的Control
-
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_0 72 小键盘数字0
-
KP_1 73 小键盘数字1
-
KP_2 74 小键盘数字2
-
KP_3 75 小键盘数字3
-
KP_4 76 小键盘数字4
-
KP_5 77 小键盘数字5
-
KP_6 78 小键盘数字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 小键盘的删除键
-
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_Mutiply 63 小键盘的*按键
-
KP_Next 89 小键盘的PageDown按键
-
KP_Prior 81 小键盘的PageUp按键
-
KP_Right 85 小键盘的→按键
-
KP_Subtract 82 小键盘的-按键
-
KP_Up 80 小键盘的↑按键
-
Next 105 PageDown按键
-
Num_Lock 77 NumLock(数字锁定)按键
-
Pause 110 Pause(暂停)按键
-
Print 111 PrintScrn(打印屏幕)按键
-
Prior 99 PageUp按键
-
Return 36 Enter(回车)按键
-
Right 102 →按键
-
Scroll_Lock 78 ScrollLock按键
-
Shift_L 50 左边的Shift按键
-
Shift_R 62 右边的Shift按键
-
Tab 23 Tab(制表)按键
-
Up 98 ↑按键
可以通过如下程序试验:
-
from tkinter import *
-
root =Tk()
-
def callback(event):
-
print(event.keysym)
-
print(event.keycode)
-
frame = Frame(root, width=200, height=200)
-
frame.bind("<Key>", callback) #组件想要响应键盘事件,组件必须获得焦点,组件才会响应键盘来的消息。因为一个窗口可以有很多组件,键盘一次敲击不知道给哪个组件。
-
frame.focus_set() #通过focus_set方法获得焦点。也可以设置Frame的takefocus选项为True,然后使用Tab将焦点转移上来
-
frame.pack()
-
mainloop()