文章目录
- 事件绑定的基本简介
- Widget 的 command 参数
- 事件绑定
- 鼠标相关的事件参数
- 鼠标绑定的基本应用
- 键盘相关的事件参数
- 键盘绑定的基本应用
- 可打印的字符
- 打印字符的基本应用
- 组合键
- 组合键的基本应用
- 窗体事件
- 窗体事件绑定的基本应用
- Event
- Event的基本应用
- 对于ASCII的说明
- 取消绑定
- 一个事件绑定多个事件处理程序
- Protocols
事件绑定的基本简介
其实GUI程序是一种事件导向
的应用程序设计,事件的来源可能是用户单击鼠标、键盘输入或是Widget 状态改变。tkinter提供一些机制让我们可以针对这些事件做更进一步的处理,这些处理的方式称为事件处理程序
Widget 的 command 参数
例子
:复习
import tkinter
def show():
label.config(text="Click")
def oneVar():
if varOne.get():
label.config(text="One!!!")
else:
label.config(text="One")
def twoVar():
if varTwo.get():
label.config(text="Two!!!")
else:
label.config(text="Two")
root = tkinter.Tk()
root.geometry("300x200")
btu = tkinter.Button(root, text="Click", command=show)
btu.pack(anchor=tkinter.W)
varOne = tkinter.BooleanVar()
cbnOne = tkinter.Checkbutton(root, text="One", variable=varOne, command=oneVar)
cbnOne.pack(anchor=tkinter.W)
varTwo = tkinter.BooleanVar()
cbnTwo = tkinter.Checkbutton(root, text="Two", variable=varTwo, command=twoVar)
cbnTwo.pack(anchor=tkinter.W)
label = tkinter.Label(root, bg="lightgreen", fg="red", height=2, width=12, font="Times 16 bold")
label.pack()
root.mainloop()
运行结果:
我们通过command=show
,来设计show函数,这个show函数就是事件处理程序
事件绑定
语法格式如下
widget.bind(event, handler)
参数:
- widget:事件的来源,可以是root窗口对象,或是任意的Widget控件,例如,功能按钮,选项按钮,复选框等等
- 第一个参数:
evevt
,事件的参数,下面具体说明 - 第二个参数:
handler
,事件处理程序,也就是根据event来触发的函数
下面我们来看具体参数
鼠标相关的事件参数
鼠标事件 | 说明 |
<Button-1> | 鼠标左键单击 |
<Button-2> | 鼠标中键单击 |
<Button-3> | 鼠标右键单击 |
<Button-4> | 鼠标滑轮向上滚动(Linux) |
<Button-5> | 鼠标滑轮向下滚动(Linux) |
<B1-Motion> | 鼠标左键拖动 |
<B2-Motion> | 鼠标中键拖动 |
<B3-Motion> | 鼠标右键拖动 |
<ButtonRelease-1> | 鼠标左键释放 |
<ButtonRelease-2> | 鼠标中键释放 |
<ButtonRelease-3> | 鼠标右键释放 |
<Double-Button-1> | 鼠标左键双击 |
<Double-Button-2> | 鼠标中键双击 |
<Double-Button-3> | 鼠标右键双击 |
<Enter> | 鼠标指针进入控件 |
<Leave> | 鼠标指针离开控件 |
上述的参数,执行后鼠标光标相对控件的位置会被存入事件对象的x和y变量中,所以这就是为什么我们在handler函数中要加入event
形参,这个是必须要传的
注:
<1> = <Button-1> =<ButtonPress-1>
<2> = <Button-2> = <ButtonPress-2>
<3> = <Button-3> =<ButtonPress-3>
这是通用的,<>
不能省略
绑定的方式
button.bind("<Button-1>", handler)
鼠标绑定的基本应用
例子
:鼠标移动,右下方看到鼠标目前的坐标
import tkinter
def moving(event):
# .x_root, .y_root是相对于整个屏幕
# 获取x轴坐标(相对于窗口)
x = event.x
# 获取y轴坐标(相对于窗口)
y = event.y
textvar = "坐标 : x:%r y:%r" % (x, y)
var.set(textvar)
root = tkinter.Tk()
root.geometry("300x200")
x, y = 0, 0
var = tkinter.StringVar()
text = "坐标 : x:%r y:%r" % (x, y)
var.set(text)
label = tkinter.Label(root, textvariable=var)
label.pack(anchor=tkinter.S, side=tkinter.RIGHT, padx=10, pady=10)
# 事件是鼠标移动,执行moving函数
root.bind("<Motion>", moving)
root.mainloop()
运行结果:
moving(event)中的event
是可以自定义的,但是不能没有
键盘相关的事件参数
键盘事件 | 说明 |
<Return> | 回车 |
<Cancel> | Break键 |
<BackSpace> | BackSpace键 |
<Tab> | Tab键 |
<Shift_L> | 左Shift键 |
<Alt_L> | 左Alt键 |
<Control_L> | 左Control键 |
<Shift_R> | 右Shift键 |
<Alt_R> | 右Alt键 |
<Control_R> | 右Control键 |
<Pause> | Pause键 |
<Caps_Lock> | Caps_Lock键 |
<Escape> | Escapel键,俗称Esc |
<Prior> | PageUp键 |
<Next> | PageDown键 |
<End> | End键 |
<Home> | Home键 |
<Left> | 左箭头 |
<Up> | 上箭头 |
<Right> | 右箭头 |
<Down> | 下箭头 |
<Print> | Print Screen |
<Insert> | Insert键 |
<Delete> | Delete键 |
<F1> | F1键 |
<F2> | F2键 |
<F3> | F3键 |
<F4> | F4键 |
<F5> | F5键 |
<F6> | F6键 |
<F7> | F7键 |
<F8> | F8键 |
<F9> | F9键 |
<F10> | F10键 |
<F11> | F11键 |
<F12> | F12键 |
<Num_Lock> | Num_Lock键 |
<Scroll_Lock> | Scroll_Lock键 |
<plus> | 小键盘上的 + 键 |
<minus> | 小键盘上的 - 键 |
<asterisk> | 小键盘上的 * 键 |
<slash> | 小键盘上的 / 键 |
<key> | 任意键 |
注:
<key> = <KeyPress> = <KeyRelease>
键盘绑定的基本应用
例子
:当我们按下Tab
时,tkinter做出响应
import tkinter
def tab(event):
# keysym 键盘事件对应的字符串
print(f"按下了{event.keysym}键")
root = tkinter.Tk()
root.geometry("100x80")
root.bind("<Tab>", tab)
root.mainloop()
运行结果:
可打印的字符
字符 | 说明 |
<a> | 字母a |
<b> | 字母b |
此处省略剩下的24个字母 | 此处省略剩下的24个字母 |
<1> | 数字1 |
<2> | 数字2 |
此处省略剩下的8个数字 | 此处省略剩下的8个数字 |
<A> | 按键shift+a或者字母大写A |
<B> | 按键shift+b或者字母大写B |
此处省略剩下的24个大写字母 | 此处省略剩下的24个写字母 |
注:
<a> = <Key-a> = <KeyPress-a> = <KeyRelease-a>
打印字符的基本应用
例子
:当我们按下a
时,tkinter做出响应
import tkinter
def tab(event):
print(f"按下了{event.keysym}键")
root = tkinter.Tk()
root.geometry("100x80")
root.bind("<a>", tab)
root.mainloop()
运行结果:
组合键
组合键 | 说明 |
<Shift-Home> | Shift+Home |
<Alt-Home> | Alt+Home |
<Control-Home> | Ctrl+Home |
<Control-A> | Ctrl+shift+a |
注:
组合键不止这些,可以自由组合
组合键的基本应用
例子
:当我们按下Alt+Home
时,tkinter做出响应
import tkinter
def tab(event):
print(f"按下了home键")
root = tkinter.Tk()
root.geometry("100x80")
root.bind("<Alt-Home>", tab)
root.mainloop()
运行结果:
窗体事件
窗体事件 | 说明 |
<Configure> | 改变大小或位置 |
<Visibility> | 当组件变为可视状态时触发 |
<Unmap> | 当组件由显示状态变为隐藏状态时触发 |
<Map> | 当组件由隐藏状态变为显示状态时触发 |
<Expose> | 当组件从原本被其他组件遮盖的状态中暴漏出来时触发 |
<FocusIn> | 组件获得焦点时触发 |
<FocusOut> | 组件失去焦点时触发 |
<Circulate> | 当窗体由于系统协议要求在堆栈中置顶或压底时触发 |
<Colormap> | 当窗体的颜色或外貌改变时触发,Tk中忽略此细则 |
<Property> | 当窗体的属性被删除或改变时触发,属于TK的核心 |
<Destroy> | 当组件被销毁时触发 |
<Activate> | 与组件选项中的state项有关,表示组件由不可用变为可用时触发 |
<Deactiavte> | 与组件选项中的state项有关,表示组件由可用变为不可用时候触发 |
窗体事件绑定的基本应用
例子
:获得焦点与失去焦点,由Tab键进行切换
import tkinter
def a(event):
label.config(text="获取焦点")
def b(event):
label.config(text="失去焦点")
root = tkinter.Tk()
root.geometry("300x200")
btu = tkinter.Button(root, text="Click")
btu.pack(anchor=tkinter.W)
btu.bind("<FocusIn>", a)
btu.bind("<FocusOut>", b)
btu1 = tkinter.Button(root, text="Other")
btu1.pack(anchor=tkinter.W)
label = tkinter.Label(root, bg="lightgreen", fg="red", height=2, width=12, font="Times 16 bold")
label.pack()
root.mainloop()
运行结果:
例子
:组件由隐藏状态变为显示状态,显示状态变为隐藏状态
from tkinter import *
def show(event):
b2.config(bg="lightyellow")
# SystemButtonFace 默认的颜色,就是那个灰色
b1.config(bg="SystemButtonFace")
def Unshow(event):
b1.config(bg="lightblue")
b2.config(bg="SystemButtonFace")
root = Tk()
l1 = Label(root, text='pack_forget')
b3 = Button(root, text='按钮')
b3.bind("<Unmap>", Unshow)
b3.bind("<Map>", show)
# pack_forget 不显示
b1 = Button(root, text='隐藏', command=b3.pack_forget)
b2 = Button(root, text='显示', command=b3.pack)
l1.pack(fill=X)
b1.pack(fill=X)
b2.pack(fill=X)
b3.pack()
root.mainloop()
运行结果:
Event
Event | 说明 |
widget | 事件被触发的控件 |
.x, .y | 鼠标距离窗体左上角的位置(坐标) |
.x_root, .y_root | 鼠标距离屏幕左上角的位置(坐标) |
.char | 键盘事件对应的字符代码 |
.keysym | 键盘事件对应的字符串 |
.keycode | 键盘事件对应的按键码 |
.num | 鼠标事件对应的按键码 |
.width, .height | 控件的新大小 |
.type | 事件类型 |
Event的基本应用
例子
:键盘输入,tkinter响应字符串和按键码(ASCII)
import tkinter
def show(event):
print(f"{event.keysym}对应的ASCII码:{event.keycode}")
win = tkinter.Tk()
win.geometry("150x100")
win.bind("<Key>", show)
win.mainloop()
运行结果:
对于ASCII的说明
每套键盘可能对应的ASCII都不同,所以在这里我并没有写明每个字母、字符、数字的ASCII值,即使写了可能也与大家的ASCII值不同,怎样得知自己键盘的ASCII值呢?
上述的方法获取是最好验证的,请参照Event的基本应用
中的例子
取消绑定
取消绑定xx
的方法如下:
# <xxx>是绑定方式
xx.unbind("<xxx>")
例子
:
import tkinter
def show(event):
label.config(text="ForPython!")
def choose(x):
if var.get():
x.bind("<Button-1>", show)
else:
label.config(text="")
x.unbind("<Button-1>")
root = tkinter.Tk()
root.geometry("300x200")
btu = tkinter.Button(root, text="Click")
btu.pack(anchor=tkinter.W)
var = tkinter.BooleanVar()
cbut = tkinter.Checkbutton(root, text="bind/unbind", variable=var, command=lambda: choose(btu))
cbut.pack(anchor=tkinter.W)
label = tkinter.Label(root, bg="lightgreen", fg="red", height=2, width=12, font="Times 16 bold")
label.pack()
root.mainloop()
运行结果:
一个事件绑定多个事件处理程序
使用bind()
方法可以绑定一个事件处理程序,tkinter也允许我们执行一个事件绑定多个事件处理程序,同样使用bind()
方法,但是新增加的时间处理程序需要在bind()方法内增加参数add = "+"
例子
:
import tkinter
def show():
print("???")
def shower(event):
print("!!!")
root = tkinter.Tk()
button = tkinter.Button(root, text="Click", command=show)
button.pack()
button.bind("<1>", shower, add="+")
root.mainloop()
程序会先执行bind()
绑定的程序,然后再执行Button()
内command
指定的程序
Protocols
Protocols 可以翻译为通信协议
,在tkinter内可以解释为窗口管理程序
(Windows Manager)与应用程序
(Application)之间的通信协议
。tkinter也支持使用绑定概念更改此通信协议
例子
:退出程序询问是否要退出
import tkinter
from tkinter import messagebox
def show():
res = messagebox.askokcancel("提示", "请问您确定要退出吗?")
if res:
root.destroy()
else:
return
root = tkinter.Tk()
root.protocol("WM_DELETE_WINDOW", show)
root.mainloop()
运行结果:
谢谢观看,笔者会持续更新,如有错误或者建议,请私信我