Tkinter事件处理

Tkinter应用会花费大部分的时间在处理事件循环中(通过mainloop()方法进入),事件可以是触发的鼠标,键盘的操作,管理窗口触发的重绘事件(在多数情况下都是有用户间接引起的)。

Tkinter提供了一个强大的机制,可以让你自由的去处理事件,对于每个组件来说。可以通过bond()方法将函数或者方法绑定到具体的事件上。当触发器的事件满足该组件的事件时,Tkinter()就会带着事件取调用handler()方法。

 from tkinter import *

 root = Tk()
def callbach(event):
print("点击位置:",event.x,event.y)
frame = Frame(root,width=,height=)
frame.bind("<Button-1>",callbach)
frame.pack()
mainloop()

执行结果:

在例子中,使用Frame组件的bind()方法将鼠标的单击事件和自定义的callbach()方法绑定起来,那么运行的结果就是:当鼠标点击的时候,IDLE会相应的将鼠标的位置显示出来。

只有当组件获得焦点的时候才能接收键盘事件(Key),下面的例子中将用focus_set()获得焦点,可以设置Frame的takefocus选项为True,然后将焦点转移上来。

 from tkinter import *

 root = Tk()
def callbach(event):
print("点击位置:",event.x,event.y)
frame = Frame(root,width=,height=)
frame.bind("<Key>",callbach)
frame.focus_set()
frame.pack()
mainloop()

执行结果:

在来实现一个展示捕获鼠标轨迹的组件,需要关注的是事件。

 from tkinter import *

 root = Tk()
def callbach(event):
print("点击位置:",event.x,event.y)
frame = Frame(root,width=,height=)
frame.bind("<Motion>",callbach)
frame.pack()
mainloop()

执行结果:

事件序列

Tkinter使用一种称之为事件序列的机制运行用户定义事件,用户需要使用bind()方法将具体的事件序列与自定义的方法做绑定。事件序列以字符串的形式表示的,可以是一个或多个相关联的事件(如果多个事件,需要对应的方法只有在满足所有事件的前提下才会满足)。

事件序列使用一下语法描述:

<modifier-type-detail>

修饰 部分为可选内容,一般在组合事件中用于多功能按键组合的描述。如:Ctrl + Shift + V;

类型 部分用于描述一般的事件对象类型,如键盘按键或鼠标动作等;

type区域是事件说明符中最重要的部分,它说明我们想绑定哪一类的事件

例如Button\Key或者如进入、配置之类的窗口管理事件。

详细描述 部分为可选内容,一般用于描述事件具体单元对象,如KeyPress-A,表示按键盘A键

Modifier和detail区域用于额外的信息

在许多情况下可以省略,还有各种方法来简化事件字符串,例如为了匹配键盘键,您可以省略

尖括号,只需使用键,当然要包含在尖括号内让我们来看看最常见的事件格式

事件格式

<Button-1>鼠标左键按下事件,1表示左键;2-鼠标中键;3-鼠标右键

当您在组件上按下鼠标左键,随后的鼠标事件(移动、释放)就会发送到当前组件,即使

鼠标移动到当前组件之外,鼠标指针的的当前位置在传递给回调函数的event对象的x,y中

<Button-1>、<ButtonPress-1>、<1>都是同义词

<B1-Motion>按住鼠标左键移动鼠标,鼠标指针的当前位置在传递给回调函数的event中的x\y提供

<ButtonRelease-1>鼠标左键被释放

<Double-Button-1>鼠标左键被双击,你可以用Double表示双击,还可以用Triple表示三击

注意,如果你绑定了<Button-1>和<Double-Button-1>,那么2个事件都被触发

键入部分常用的关键字及含义

事件类型

意义描述

Activate

组件状态变化事件,未激活变为激活时触发;

与 Deactivate 相对

Button

鼠标按键点击事件;

由描述部分指定具体按键:

  <Button-1> 鼠标左键

  <Button-2> 鼠标中键

  <Button-3> 鼠标右键

  <Button-4> 滚轮上(linux)

  <Button-5> 滚轮下(linux)

ButtonRelease

释放鼠标按键事件。强调释放动作

Configure

组件尺寸改变事件

Deactivate

组件状态改变事件。激活变为未激活;

与 Activate 相对

Destroy

组件被销毁触发事件

Enter

鼠标指针进入组件区域事件;

与 Leave 相对

Expose

窗口或组件的部分被显示时触发事件,比如某部分被置顶

FocusIn

获得焦点事件。如果组件的takefocus属性为True,则用户可通过Tab按键切换组件焦点。也可用focus_set()方法设置组件焦点

FocusOut

失去焦点事件

KeyPress

键盘按键事件。强调按下动作;

由描述部分指定具体按键,如 <KeyPress-A>、<KeyPress-B>;

可简写为Key

KeyRelease

释放键盘按键事件。强调释放动作

Leave

鼠标指针离开组件区域事件;

与 Enter 相对

Map

组件被映射时触发事件。指在程序中,该组件被调用(组件显示、隐藏等)。如调用grid()方法

Motion

鼠标在组件区域内移动事件

MouseWheel

鼠标滚轮事件。该事件序列支持Windows和Mac 等同于Linux下的Button-4/5

Unmap

组件被取消映射事件;

与Map相对

Visibility

应用程序至少有一部分被置顶(即被显示出来)事件

<Shift-Up>

用户按下shift键同时按下向上键触发,也可以用Alt,shift,control

frame1.bind("<Shift M>",shiftm) 当同时按下shift 和m 后回调函数shiftm

<Return>

用户按下回车键,你可以绑定键盘上几乎所有键,Shift_L(左边的shift键)

Delete\F1\F5\Num_Lock都可以

修饰语

修饰符

意义

Alt

按下Alt键

Any

按下任意键。如<Any-KeyPress>,表示按下任意键事件

Control

按下Ctrl键

Double

被修饰的事件类型连续两次触发。如<Double-Button-1>,表示双击鼠标左键

Lock

大写字母锁定键

Shift

按下Shift

Triple

被修饰的事件类型连续三次触发

事件对象

当Tkinter回调预定义的函数时,将带着事件对象(作为参数)去掉用。

事件对象的属性及含义

属性

意义描述

widget

产生事件的组件

x,y

以窗口左上角为原点,鼠标指针的坐标。以像素为单位

x_root,y_root

以屏幕左上角为原点,鼠标指针的坐标,以像素为单位

char

键盘按键字符

keysym

键盘按键名

keycode

键盘按键码

num

鼠标按钮数字

width,height

组件尺寸改变后的宽和高

type

事件类型

当事件为,,的时候,细节可以通过设定具体的按键名来筛选,例如表示按下键盘的大写字母H的时候触发事件,表示按下键盘上的Tab键的时候触发事件。

列举了键盘的所有特殊按键的keysym和keycode(其中的按键码是对应美国标准101键盘的latin-1字符集,键盘标准不同对应的按键码不同,但按键名是一样的。)

键盘所有特殊按键的键符和键码

按键名(keysym)

按键码(keycode)

按键描述

Alt_L

64

左Alt

Alt_R

113

右Alt

BackSpace

22

退格

Cancel

110

break键

Caps_Lock

66

大写字母锁定

Control_L

37

左Ctrl

Control_R

109

右Ctrl

Shift_L

50

左Shift

Shift_R

62

右Shift

Insert

106

插入键

Delete

107

删除键

Left

100

左方向键

Right

102

右方向键

Up

98

上方向键

Down

104

下方向键

Home

97

Home键

End

103

End键

Escape

9

Esc键

Execute

111

Sysreq键

F1~F11

67~77

F1键到F11键(一一对应)

F12

96

F12键

Linefeed

54

Linefeed键(Ctrl + J)

KP_0

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_Subtract

82

数字键盘 -

KP_Add

86

数字键盘 +

KP_Begin

84

数字键盘中间键(5)

KP_Decimal

91

数字键盘点键

KP_Delete

91

数字键盘删除

KP_Divide

112

数字键盘反斜杠 /

KP_Up

80

数字键盘上方向

KP_Left

83

数字键盘左方向

KP_Right

85

数字键盘右方向

KP_Down

88

数字键盘下方向键

KP_End

87

数字键盘End键

KP_Enter

108

数字键盘回车

KP_Home

79

数字键盘Home

KP_Insert

90

数字键盘插入

KP_Multiply

63

数字键盘星号 *

KP_Next

89

数字键盘PageDown

KP_Prior

81

数字键盘PageUp

Next

105

PageDown键

Num_Lock

77

数字键盘锁定

Pause

110

Pause暂停

Print

111

屏幕打印

Prior

99

PageUp键

Return

36

回车

Scroll_Lock

78

ScrollLock键

Tab

23

制表按键

按键名(keysym)

按键码(keycode)

按键描述

Alt_L

64

左Alt

Alt_R

113

右Alt

BackSpace

22

退格

Cancel

110

break键

Caps_Lock

66

大写字母锁定

Control_L

37

左Ctrl

Control_R

109

右Ctrl

Shift_L

50

左Shift

Shift_R

62

右Shift

实例和类的绑定

以上的例子中我们用的都是在实例上使用bind方法,这意味着这样只能bind在一个组件上,

如果我们创建一个新的组件,他们不会继承这些绑定关系。

不过Tkinter也提供了类级别和应用级别的bind,实际上,你可以使用以下级别的binding

1.组件实例

2.组件的顶层窗体(Toplevel 或者 root)

3.组件类,用bind_class方法

4.整个应用,用bind_all方法

比如,你可以用bind_all来绑定F1按钮的点击,这样你能在这个应用的如何地方点击都可以弹出帮助框

但如果同一个键你在多处绑定了怎么办?

首先,在以上4个层次之内,Tkinter选择最接近匹配的方式。比如为<Key>

和<Return>事件创建实例绑定,那么只有按下Enter键之后才会调用<Return>的回调函数

但是,如果你如果在以上4个层次间,比如你同时向toplevel组件添加<Return>绑定,那么将调用2个绑定

Tkinter首先调用实例级别的最佳绑定,最后在应用程序级别调用最佳可用绑定,因此,

在极端情况下,单个事件可以调用4个事件处理程序。

常见的混乱原因是当您尝试使用绑定来覆盖标准组件的默认行为。例如,假设你想在

文本框内禁止输入回车键,这样用户就无法输入多行数据,也行你会用下面的小伎俩

 def ignore(event):
pass text.bind("<Return>",ignore)

或者,你喜欢一行的简洁代码

text.bind("<Return>",lamdba e:None)

不幸的是,新的一行依然会插入,因为,以上的绑定仅仅应用在应用级别,

而标准的行为依然有类级别的绑定实现了。

你可以使用bind_class方法来改变类级别的绑定,但这将更改应用程序中所有文本组件的行为。下面是比较合理的解决办法

 def ignore(event):
return "break"
text.bind("<Return>", ignore)

顺便说一句,如果你真的想改变所有文本组件的默认行为,你可以用以下bind_class方法

top.bind_class("Text", "<Return>", lambda e: None)

真的不建议这么做,不要改变组件的默认行为。

协议

除了事件绑定,Tkinter还提供了协议处理的机制,这里的协议指的是应用程序和windows manager之间的互动

最常见的是WM_DELETE_WINDOW,用于定义当用户使用窗口管理器显式关闭窗口是的事件。

你可以用protocol方法来安装这个协议的回调函数(这个组件必须是root或者Toplevel组件)

widget.protocol("WM_DELETE_WINDOW", handler)

一旦你注册了自己的处理函数,Tkinter将不再自动的关闭程序,比如下面这个例子

from Tkinter import *
import tkMessageBox def callback():
if tkMessageBox.askokcancel("Quit", "Do you really wish to quit?"):
root.destroy() root = Tk()
root.protocol("WM_DELETE_WINDOW", callback)
root.mainloop()

注意,即使你没有在顶层窗口注册WM_DELETE_WINDOW的处理程序,窗口还是会被销毁的。最好还是自己注册一个处理程序

top = Toplevel(...)#确保窗口小部件实例被删除
top.protocol(“WM_DELETE_WINDOW”,top.destroy)

GUI的最终选择 Tkinter(九):事件的更多相关文章

  1. Python之GUI的最终选择(Tkinter)

    首先,Tkinter是Python默认的GUI库,想IDLE就是用Tkinter设计出来的,因此直接导入Tkinter模块就可以啦 1 import tkinter (1)Tkinter初体验: 1 ...

  2. GUI的最终选择Tkinter模块初级篇

    一.Tkinter模块的基本使用 1)实例化窗口程序 import tkinter as tk app = tk.Tk() app.title("FishC Demo") app. ...

  3. GUI的最终选择 Tkinter(五):Text用法

    Text组件 绘制单行文本使用Label组件,多行选使用Listbox,输入框使用Entry,按钮使用Button组件,还有Radiobutton和Checkbutton组件用于提供单选或多选的情况, ...

  4. GUI的最终选择 Tkinter(一):Tkinter最初体验

    EasyGui就是一个简单的文字交互界面模块,从今天开始来开始学习Tkinter Tkinter是Python标准的Gui库,它实际是建立在Tk技术上的,Tk最初是为Tcl(一门工具名语言)所涉及的, ...

  5. GUI的最终选择 Tkinter(七):菜单Menu组件、Menubutton组件、OptionMenu组件

    Menu组件 今天说的Menu组件就是一些菜单组件,开始点点点... Tkinter提供了一个Menu组件,可以实现顶级菜单,下拉菜单和弹出菜单.由于底层是代码实现和优化的,所以不太建议通过按钮和其他 ...

  6. GUI的最终选择 Tkinter(四):Entry、Listbox、Scrollbar和Scale组件

    Entry组件 Entry组件就是平时所说的输入框.输入框是程序员用到的最多的一个程序,例如在输入账号和密码的时候需要提供两个输入框,用于接收密码的输入框还会有星号将实际输入的内容隐藏起来. Tkin ...

  7. GUI的最终选择 Tkinter(三):Checkbutton组件和Radiobutton组件、LabelFrame组件

    Checkbutton组件 Checkbutton组件就是常见的多选按钮,而Radiobutton则是单选按钮 from tkinter import * root = Tk() v = IntVar ...

  8. GUI的最终选择 Tkinter(六):Canvas组件

    Canvas组件,是一个可以让你任性的组件,一个可以让你随心所欲地绘制界面的组件.Canvas是一个通用的组件,它通常用于显示和编辑图形,可以用它来绘制直线,圆形,多边形,甚至是绘制其他组件. 在Ca ...

  9. GUI的最终选择Tkinter模块练习篇

    一.Canvas画布练习 1)简单的绘制图框 from tkinter import * # 构建一个窗口 tk = Tk() # 画布 canvas= Canvas(tk,width=,height ...

随机推荐

  1. html5--2.1新的布局元素(1)-header/footer

    html5--2.1新的布局元素(1)-header/footer 学习要点 了解header/footer的语义和用法 使用header/footer进行一个简单的布局 header元素(标签) 用 ...

  2. 集训Day1

    雅礼集训2017Day1的题 感觉上不可做实际上还挺简单的吧 T1 区间加 区间除法向下取整 查询区间和 区间最小值 大力上线段树,把除法标记推到底,加法标记就是按照线段树的来 先拿30 然后60的数 ...

  3. ACM学习历程—HDU1028 Ignatius and the Princess(组合数学)

    Ignatius and the Princess Description        "Well, it seems the first problem is too easy. I w ...

  4. Codeforces 762C Two strings 字符串

    Cpdeforces 762C 题目大意: 给定两个字符串a,b\((len \leq 10^5)\),让你去b中的一个连续的字段,使剩余的b串中的拼接起来的两个串是a穿的子序列.最大化这个字串的长度 ...

  5. 结合Django+celery二次开发定时周期任务

    需求: 前端时间由于开发新上线一大批系统,上完之后没有配套的报表系统.监控,于是乎开发.测试.产品.运营.业务部.财务等等各个部门就跟那饥渴的饿狼一样需要 各种各样的系统数据满足他们.刚开始一天一个还 ...

  6. java定时器,留着用

    说明:该定时器作用是 设定定时器首次执行的时间firstTime和执行间隔period,如firstTime=2015-3-25 9:00:00,period=24小时,若程序启动时,已经超过firs ...

  7. bzoj1072Perm——状压DP

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1072 数字串最多只有10位,所以考虑用状压: 压缩的状态是哪些数字被用过,这样可以从一种状态 ...

  8. 洛谷P1941飞扬的小鸟——细节DP

    题目:https://www.luogu.org/problemnew/show/P1941 此题主要注意许多细节,详见代码. 代码如下: #include<iostream> #incl ...

  9. docker 学习(八) docker file

    一 什么是Dockerfile: Dockerfile是由一系列命令和参数构成的脚本,这些命令应用于基础镜像并最终创建一个新的镜像.它们简化了从头到尾的流程并极大的简化了部署工作.Dockerfile ...

  10. object类型转换为Array类型

    var obj = {a: 1, b: 2, c: 3}; // .... var arr = []; for(var key in obj){ if(!obj.hasOwnProperty(key) ...