鱼c笔记——Python的GUI编程(十一):Tkinter事件绑定

一个Tkinter应用程序大部分时间是花在事件循环当中的,也就是通过mainloop()进入的事件循环。

事件可以有各种来源:用户触发的鼠标和键盘操作和窗口管理器触发的重绘事件(在多数情况下是由用户简介引起的)

Tkinter给我们提供了一个强大的机制去管理这些事件,去定义这些事件的操作。对每一个组件来说,可以通过bind()的方法来将自己定义的函数或方法绑定到具体的事件上。

widget.bind(event, handler)

 

当被触发的事件满足该组件绑定的事件的时候,Tkinter就会带着事件对象(Event、事件本身的描述)去调用自定义的handler()方法。

 

 

捕获鼠标点击的位置的演示:

 
  1. from tkinter import *

  2.  
  3. root =Tk()

  4.  
  5. #当触发<Button-1>,Tkinter会带着事件本身去调用callback,会把它传入到callback中,因此要个形参来接收对应的事件描述

  6. def callback(event):

  7. print("点击位置:", event.x, event.y) #这个x和y表示的是相对于应用程序左上角的x和y。root的x和y相对的是屏幕

  8.  
  9. frame = Frame(root, width=200, height=200)

  10. frame.bind("<Button-1>", callback) # -左边是事件本身,右边是事件详细描述。Button表示的是鼠标的点击事件,1表示的是左键,2代表滚轮,3表示右键,4、5对于Linux系统才有用,表示滚轮向上滚和向下滚。对于Windows和Mac系统来说则是通过mousewhell来表示用户是向上滚还是向下滚了滚轮。

  11. frame.pack()

  12.  
  13. mainloop()

 

关于键盘的演示:

 
  1. from tkinter import *

  2.  
  3. root =Tk()

  4.  
  5. def callback(event):

  6. print(event.char) #获取当前键盘按下的字符

  7.  
  8. frame = Frame(root, width=200, height=200)

  9. frame.bind("<Key>", callback) #组件想要响应键盘事件,组件必须获得焦点,组件才会响应键盘来的消息。因为一个窗口可以有很多组件,键盘一次敲击不知道给哪个组件。

  10. frame.focus_set() #通过focus_set方法获得焦点。也可以设置Frame的takefocus选项为True,然后使用Tab将焦点转移上来

  11. frame.pack()

  12.  
  13. mainloop()

 

利用<Motion>事件获取鼠标实时位置的方式

 
  1. from tkinter import *

  2.  
  3. root =Tk()

  4.  
  5. def callback(event):

  6. print("当前位置:", event.x, event.y)

  7.  
  8. frame = Frame(root, width=200, height=200)

  9. frame.bind("<Motion>", callback) #Motion事件表示当鼠标进入组件时,就会响应这个事件

  10. frame.focus_set()

  11. frame.pack()

  12.  
  13. 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”字符集,键盘标准不同,对应的按键码不同,但按键名是一样的)

 
  1. 按键名(keysym) 按键码(keycode) 代表的按键

  2. Alt_L 64 左边的Alt按键

  3. Alt_R 113 右边的Alt按键

  4. BackSpace 22 BackSpace(退格)按键

  5. Cancel 110 break按键

  6. Caps_Lock 66 CapsLock(大写字母锁定)按键

  7. Control_L 37 左边的Control

  8. Control_R 109 右边的Control

  9. Delete 107 Delete按键

  10. Down 104 ↓按键

  11. End 103 End按键

  12. Escape 9 Esc按键

  13. Execute 111 SysReq按键

  14. F1 67 F1按键

  15. F2 68 F2按键

  16. F3 69 F3按键

  17. F4 70 F4按键

  18. F5 71 F5按键

  19. F6 72 F6按键

  20. F7 73 F7按键

  21. F8 74 F8按键

  22. F9 75 F9按键

  23. F10 76 F10按键

  24. F11 77 F11按键

  25. F12 96 F12按键

  26. Home 97 Home按键

  27. Insert 106 Insert按键

  28. Left 100 ←按键

  29. Linefeed 54 Linefeed(Ctrl + J)

  30. KP_0 72 小键盘数字0

  31. KP_1 73 小键盘数字1

  32. KP_2 74 小键盘数字2

  33. KP_3 75 小键盘数字3

  34. KP_4 76 小键盘数字4

  35. KP_5 77 小键盘数字5

  36. KP_6 78 小键盘数字6

  37. KP_7 79 小键盘数字7

  38. KP_8 80 小键盘数字8

  39. KP_9 81 小键盘数字9

  40. KP_Add 86 小键盘的+按键

  41. KP_Begin 84 小键盘的中间按键(5)

  42. KP_Decimal 91 小键盘的点按键(.)

  43. KP_Delete 91 小键盘的删除键

  44. KP_Divide 112 小键盘的/按键

  45. KP_Down 88 小键盘的↓按键

  46. KP_End 87 小键盘的End按键

  47. KP_Enter 108 小键盘的Enter按键

  48. KP_Home 79 小键盘的Home按键

  49. KP_Insert 90 小键盘的Insert按键

  50. KP_Left 83 小键盘的←按键

  51. KP_Mutiply 63 小键盘的*按键

  52. KP_Next 89 小键盘的PageDown按键

  53. KP_Prior 81 小键盘的PageUp按键

  54. KP_Right 85 小键盘的→按键

  55. KP_Subtract 82 小键盘的-按键

  56. KP_Up 80 小键盘的↑按键

  57. Next 105 PageDown按键

  58. Num_Lock 77 NumLock(数字锁定)按键

  59. Pause 110 Pause(暂停)按键

  60. Print 111 PrintScrn(打印屏幕)按键

  61. Prior 99 PageUp按键

  62. Return 36 Enter(回车)按键

  63. Right 102 →按键

  64. Scroll_Lock 78 ScrollLock按键

  65. Shift_L 50 左边的Shift按键

  66. Shift_R 62 右边的Shift按键

  67. Tab 23 Tab(制表)按键

  68. Up 98 ↑按键

 

可以通过如下程序试验:

 
  1. from tkinter import *

  2.  
  3. root =Tk()

  4.  
  5. def callback(event):

  6. print(event.keysym)

  7. print(event.keycode)

  8.  
  9. frame = Frame(root, width=200, height=200)

  10. frame.bind("<Key>", callback) #组件想要响应键盘事件,组件必须获得焦点,组件才会响应键盘来的消息。因为一个窗口可以有很多组件,键盘一次敲击不知道给哪个组件。

  11. frame.focus_set() #通过focus_set方法获得焦点。也可以设置Frame的takefocus选项为True,然后使用Tab将焦点转移上来

  12. frame.pack()

  13.  
  14. mainloop()

  • 5
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值