tkinter 事件绑定#

绑定无参数的函数#

下面直接看一个事件绑定的例子:

from tkinter import ttk, Tk
from tkinter import N, W, E, S
from tkinter import StringVar

class App(ttk.Frame):
    def __init__(self, master=None):
        super().__init__(master)
        self.master = master
        self.var = StringVar()
        self.create_widgets()
        self._layout()

    def create_widgets(self):
        self.hi_there = ttk.Button(self)
        self.hi_there["text"] = "欢迎进入 GUI 世界\n(点我)"
        self.hi_there["command"] = self.say_hi
        self.print_label = ttk.Label(textvariable=self.var)
        self.quit = ttk.Button(self, text="QUIT")
        self.quit["command"] = self.master.destroy
        
        
    def _layout(self):
        self.master.title("简单的 GUI") # 添加标题
        self.master.maxsize(1000, 400) # 改变窗体尺寸
        self['padding'] = ("3 3 12 12")
        self.grid()
        self.hi_there.grid(column=0, row=0, sticky=(N, W, E, S))
        self.print_label.grid(column=0, row=1)
        self.quit.grid(column=1, row=1)

    def say_hi(self):
        self.var.set("看这里!")

root = Tk()
app = App(root)
app.mainloop()

效果图:

图1 事件绑定的一个简单例子

该例子使用 "command" 配置选项,绑定了无参数的函数 self.say_hi

绑定有参数传递的函数#

如果想要向被绑定的函数中传递参数,可以借助 lambda 匿名函数进行操作。比如,修改上面的 say_hi() 为:

def say_hi(self, *args):
    init_str = "看这里!\n"
    out = init_str + ' '.join(args)
    self.var.set(out)

并且对应的 self.hi_there["command"] = self.say_hi 修改为:

self.hi_there["command"] = lambda : self.say_hi('Tom', 'Jack', 'Lily')

或者(鼠标左键触发事件)

self.bind('<1>', lambda event: self.say_hi('Tom', 'Jack', 'Lily'))

效果图:

图2 可传递参数的绑定

事件驱动范例#

tkinter 提供了一个强大的事件驱动机制:

widget.bind(event, hander)

其中 hander 是可回调的函数等句柄。

本章以几个例子来说明事件驱动。先载入可能使用到的包:

from tkinter import ttk, Tk
from tkinter import N, W, E, S
from tkinter import StringVar

鼠标按键#

下面的代码提供了一个绑定鼠标左键的例子:

class App(Tk):
    def __init__(self):
        super().__init__()
        self.out_var = StringVar()
        self.geometry('200x200')
        self.text = ttk.Label(textvariable=self.out_var)
        self.text.grid()
        # 绑定鼠标左键
        self.bind('<1>', self.get_location)
        
    def get_location(self, event):
        self.out_var.set(f'点击的位置: {(event.x, event.y)}')
        
app = App()
app.mainloop()

该例子通过鼠标左键获取窗口的坐标位置。显示效果图:

图1 鼠标左键获取坐标

键盘按键#

使用 <Key> 可以获取键盘的按键:

class App(Tk):
    def __init__(self):
        super().__init__()
        self.out_var = StringVar()
        self.geometry('200x200')
        self.text = ttk.Label(textvariable=self.out_var)
        # 绑定鼠标左键
        self.bind('<Key>', self.get_char)
        self.text.grid()
        
    def get_char(self, event):
        self.out_var.set(f'点击的键盘字符为: {(event.char)}')
        
app = App()
app.mainloop()

效果图为:

图2 获取键盘的按键

获取鼠标移动的位置#

使用 <Motion> 可以获取鼠标的移动位置:

class App(Tk):
    def __init__(self):
        super().__init__()
        self.out_var = StringVar()
        self.geometry('200x100')
        self.text = ttk.Label(textvariable=self.out_var)
        # 绑定鼠标左键
        self.bind('<Motion>', self.stroke)
        self.text.grid()
        
    def stroke(self, event):
        self.out_var.set(f'当前的位置为: {(event.x, event.y)}')
        
app = App()
app.mainloop()

效果图:

图3 捕获鼠标当前位置