05 Tkinter事件
1. 点击事件
1.1 绑定点击事件到函数
import tkinter as tk
def button_command():
print("你点击了按钮")
root = tk.Tk()
root.geometry("500x300+100+100")
btn = tk.Button(root, text="确定", command=button_command)
btn.pack()
root.mainloop()
1.2 带参数的事件
import tkinter as tk
def sum(a, b):
print("%d + %d = %d" % (a, b, a + b))
def func():
sum(1, 1)
root = tk.Tk()
root.geometry("300x300+200+200")
btn = tk.Button(root, text="确定", command=func)
btn.pack()
root.mainloop()
2. 鼠标键盘事件
2.1 鼠标事件
import tkinter as tk
def callback(event):
print('点击位置', event.x, event.y)
root = tk.Tk()
frame = tk.Frame(root, width=200, height=200)
frame.bind("<Button-1>", callback)
frame.pack()
root.mainloop()
2.2 键盘事件
import tkinter as tk
def callback(event):
print('敲击位置', repr(event.char))
root = tk.Tk()
frame = tk.Frame(root, width=200, height=200)
frame.bind("<Key>", callback)
frame.focus_set()
frame.pack()
root.mainloop()
2.3 鼠标移动事件
import tkinter as tk
def callback(event):
print('当前位置', event.x, event.y)
root = tk.Tk()
frame = tk.Frame(root, width=200, height=200)
frame.bind("<Motion>", callback)
frame.pack()
tk.mainloop()
3. Event 对象
3.1 事件类型
事件名称 | 描述 |
---|---|
<Button-1> | 鼠标左键点击 |
<Button-2> | 鼠标中键点击 |
<Button-3> | 鼠标右键点击 |
<B1-Motion> | 鼠标左键拖动 |
<B2-Motion> | 鼠标中键拖动 |
<B3-Motion> | 鼠标右键拖动 |
<ButtonRelease-1> | 鼠标左键释放 |
<ButtonRelease-2> | 鼠标中键释放 |
<ButtonRelease-3> | 鼠标右键释放 |
<Double-Button-1> | 鼠标左键双击 |
<Triple-Button-1> | 鼠标左键三击 |
<Enter> | 鼠标进入控件 |
<Leave> | 鼠标离开控件 |
<Motion> | 鼠标移动 |
<KeyPress> | 键盘按键按下 |
<KeyRelease> | 键盘按键释放 |
<KeyPress-A> | 按下A键 |
<KeyPress-F1> | 按下F1键 |
<Control-A> | 按下Ctrl+A组合键 |
<Alt-F4> | 按下Alt+F4组合键 |
<Shift-Tab> | 按下Shift+Tab组合键 |
3.2 Event 对象属性
属性名称 | 描述 |
---|---|
type | 事件类型,如<Button-1> 、<Key> 等 |
widget | 产生事件的控件 |
x, y | 鼠标位置坐标(相对于窗口左上角,像素为单位) |
x_root, y_root | 鼠标位置坐标(相对于屏幕左上角,像素为单位) |
char | 按键对应的字符(键盘事件) |
keysym | 按键名(键盘事件) |
keycode | 按键的唯一代码(键盘事件) |
num | 按键数字(鼠标事件) |
width, height | 控件新尺寸(Configure事件) |
time | 事件发生的时间戳 |
state | 控件的状态(如是否被选中) |
serial | 事件序列号 |
send_event | 是否为发送事件 |
delta | 鼠标滚轮移动的步数 |
xview | 水平滚动条的视图位置 |
yview | 垂直滚动条的视图位置 |
4. 案例
让我们创建一个综合案例,这个程序将允许用户在画布上用鼠标绘制线条,并且可以清除画布。我们将使用Tkinter的画布组件来实现这个功能。
# 导入tkinter模块,用于创建GUI界面
import tkinter as tk
# 定义一个名为DrawingApp的类,用于管理绘图应用
class DrawingApp:
# 类的初始化方法,接收一个Tkinter窗口对象作为参数
def __init__(self, root):
# 将传入的窗口对象赋值给实例变量root
self.root = root
# 设置窗口标题为"绘图应用"
self.root.title("绘图应用")
# 创建画布
# 创建一个400x400像素的画布,背景色为白色
self.canvas = tk.Canvas(self.root, width=400, height=400, bg="white")
# 将画布添加到窗口中
self.canvas.pack()
# 绑定鼠标事件
# 绑定鼠标左键按下事件到start_line方法
self.canvas.bind("<Button-1>", self.start_line)
# 绑定鼠标左键拖动事件到draw_line方法
self.canvas.bind("<B1-Motion>", self.draw_line)
# 绑定鼠标左键释放事件到reset_line方法
self.canvas.bind("<ButtonRelease-1>", self.reset_line)
# 初始化变量
self.start_x = None # 初始化鼠标开始x坐标为None
self.start_y = None # 初始化鼠标开始y坐标为None
self.current_line = None # 初始化当前绘制的线条为None
# 定义鼠标左键按下事件的处理方法
def start_line(self, event):
# 记录开始绘制的位置
self.start_x = event.x # 记录鼠标按下的x坐标
self.start_y = event.y # 记录鼠标按下的y坐标
# 定义鼠标左键拖动事件的处理方法
def draw_line(self, event):
# 绘制线条
if self.start_x and self.start_y: # 如果开始坐标不为None
self.current_line = self.canvas.create_line(self.start_x, self.start_y, event.x, event.y) # 在画布上绘制线条
self.start_x = event.x # 更新开始x坐标为当前鼠标x坐标
self.start_y = event.y # 更新开始y坐标为当前鼠标y坐标
def reset_line(self, event): # 定义鼠标左键释放事件的处理方法
# 重置开始位置
self.start_x = None # 将开始x坐标设置为None
self.start_y = None # 将开始y坐标设置为None
def clear_canvas(self): # 定义清除画布的方法
# 清除画布
self.canvas.delete("all") # 删除画布上的所有内容
# 当直接运行这个脚本时执行以下代码
if __name__ == "__main__":
# 创建Tkinter窗口对象
root = tk.Tk()
# 创建DrawingApp实例,传入窗口对象
app = DrawingApp(root)
# 添加清除按钮
# 创建一个按钮,点击时调用clear_canvas方法
clear_button = tk.Button(root, text="清除", command=app.clear_canvas)
clear_button.pack() # 将按钮添加到窗口中
root.mainloop() # 进入Tkinter事件循环,显示窗口
在这个程序中,我们定义了一个DrawingApp
类,它初始化了一个Tkinter窗口和一个画布。我们通过bind
方法将鼠标事件绑定到相应的处理函数上:
start_line
函数记录鼠标按下的位置。draw_line
函数在鼠标移动时绘制线条。reset_line
函数在鼠标释放时重置开始位置。
此外,我们还添加了一个“清除”按钮,当点击这个按钮时,会调用clear_canvas
函数清除画布上的所有内容。