python tkinter 向command中传递参数

背景说明


tkinter 组件中经常会绑定一些事件,实现的方向是添加command关键字,后面跟一个实现的函数方法,如:command = func()。但有时你还需要向 func 函数传递必要的参数,我们常见的想法是这样:

button = tk.Button(root, text="Show me", command=action(args))

遗憾的是这样却不能实现你想要的结果。那如何才能实现传递参数呢?下面介绍两种简单的方法。

方法一、使用 partial 函数


代码示例:

from functools import partial
button = tk.Button(root,  text="Show me", command=partial(func, arg1, arg2,...))

我们可以通过使用 functools 模块中的 partial 对象来传递参数。

用例子来说明,下面是给菜单添加item并绑定事件:

colors = ['黄色','亮紫','紫灰','亮蓝','深绿','鲜红','洋红','灰色']
for c in colors:
    zrlbMenu.add_command(label=c, command=partial(mark_zrlb,c))

就会根据变量c,生成多项item执行事件。这里主要起作用的是 partial 函数,它是一个偏函数


partial 函数的语法如下:

functools.partial(func, *args, **keywords)

偏函数:是在已有的函数基础上生成一个新的函数,这新函数的功能和已有函数相同,但是,这个新函数的部分参数已被偏函数确定。简单来说,偏函数适合当函数中的某些参数值在某些场景下是定值的时候,将其简化。什么意思呢?就是省略某些不变的参数,使得代码会更加简洁

例如,要在 menu 目录下新建若干文件夹,原代码:

import os
from os import mkdir

mkdir(os.path.join('./menu', 'dir1' ))
mkdir(os.path.join('./menu', 'dir2' ))
mkdir(os.path.join('./menu', 'dir3' ))

使用 partial 修改之后,代码如下:

import os
from os import mkdir
from functools import partial

menu_join = partial(os.path.join, './menu')

mkdir(menu_join('dir1'))
mkdir(menu_join('dir2'))
mkdir(menu_join('dir3'))

menu_join 是通过偏函数 partial() 创建的一个新的函数,而不是赋值变量。menu_join 这个函数在执行时,先调用 os.path.join 并将 './dest' 作为参数传给 os.path.join,然后再传入 "dir"

来看一下 partial 的介绍1介绍2

  1. 它是用于创建一个类似原函数但有固定参数的偏函数,从字可以看出,它是一个辅助函数。
  2. 它一共有三个部分:
    1). 第一个部,即第一个参数一个函数,这个函数可以是你定义的,也可以是 python 内置函数
    2). 第二部分,是一个可变参数,*args
    3). 第三部分,是一个关键字参数
  3. 它的作用是:将所作用的函数作为 partial() 函数的第一个参数,原函数的各个参数依次作为 partial() 函数的后续参数,原函数有关键字参数的一定要带上关键字,没有的话,按原有参数顺序进行补充。

总结来说:当函数的参数个数太多,需要简化时,使用 functools.partial 可以创建一个新的函数,这个新函数可以固定住原函数的部分参数,从而在调用时更简单。

方法二、使用 lambda 函数


代码示例:

button = tk.Button(root, text="Show me", command=lambda:func(param))

我们可能通过 python 中的 lambda 函数来创建一个临时的、一次性的简单函数用来实现传递参数。但是注意,这里有一个小小的细节,lambda 函数只会在调用时执行内部语句。也就是说,如果你传递的参数是一个变量,并且这个变量值是随着条件变化的,使用它来实现时,调用时就会传入这个变量最后的值,可能就不是你预期想要传入的值。

还是上面那个菜单的例子:

colors = ['黄色','亮紫','紫灰','亮蓝','深绿','鲜红','洋红','灰色']
for c in colors:
    zrlbMenu.add_command(label=c, command=lambda:mark_zrlb(c))

变量c是变化的,但实际的效果表现出来是,c 取的值永远是最后一个值'灰色'
所以,lambda 这一方法是应用于参数是固定的变量。例如:

btnLable= tk.Button(root, text="0")
def change_number(num):
    counter = int(str(btnLable['text']))
    counter += num
    btnLable.config(text=str(counter))
    
button = tk.Button(root, text="Increase", command=lambda: change_number(5))

lambda 函数的语法如下:

lambda: argument_list: expression

常见的 lambda 函数示例:

lambda x, y: x*y            # 函数输入是x和y,输出是它们的积x*y
lambda:None                 # 函数没有输入参数,输出是None
lambda *args: sum(args)     # 输入是任意个数参数,输出是它们的和(隐性要求输入参数必须能进行算术运算)
lambda **kwargs: 1          # 输入是任意键值对参数,输出是1

python tkinter 向command中传递参数 - 简书 (jianshu.com)

Tkinter,`command`参数可以指定一个回调函数,但是该函数不能直接传递事件参数。如果需要传递事件参数,可以使用 `lambda` 函数或者 `functools.partial()` 函数来创建一个新的函数,将事件参数作为参数传递给回调函数。 以下是使用`lambda`函数传递事件参数的示例代码: ```python import tkinter as tk def callback(event): print(event.widget["text"]) root = tk.Tk() button = tk.Button(root, text="Hello") button.bind("<Button-1>", callback) button.config(command=lambda event: button.event_generate("<Button-1>")) button.pack() root.mainloop() ``` 以上代码,我们创建了一个按钮 `button`,并绑定了鼠标左键点击事件 `<Button-1>` 的回调函数 `callback`。然后,我们通过 `button.config()` 方法将 `command` 参数设置为一个 `lambda` 函数,该函数在调用时会生成 `<Button-1>` 事件,从而触发回调函数。在 `lambda` 函数,我们将事件参数 `event` 传递给了回调函数。 类似地,您也可以使用 `functools.partial()` 函数来传递事件参数,以下是示例代码: ```python import tkinter as tk import functools def callback(event, text): print(text) root = tk.Tk() button = tk.Button(root, text="Hello") button.bind("<Button-1>", functools.partial(callback, text="Hello")) button.config(command=lambda event: button.event_generate("<Button-1>")) button.pack() root.mainloop() ``` 以上代码,我们使用 `functools.partial()` 函数创建了一个新的函数 `partial_callback`,将 `callback` 函数和需要传递的参数绑定在一起。然后,我们将 `partial_callback` 函数作为回调函数绑定到按钮的单击事件上,并在 `lambda` 函数调用 `event_generate()` 方法来触发事件。在 `callback` 函数,我们可以使用传递过来的 `text` 参数。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值