lzb1001 发表于 2022-5-16 23:24:30

listbox中lambda表达式的使用

本帖最后由 lzb1001 于 2022-5-17 00:08 编辑

WIN10/PYTHON3.7.6
----------------------------
# 此例演示Listbox组件

from tkinter import *


root = Tk()



theLB = Listbox(root)
theLB.pack()



for item in ['鸡蛋', '鸭蛋', '鹅蛋', '李狗蛋']:
    theLB.insert(END, item)



Button(root, text='删除它', width=10, font=('华康少女文字 - Kelvin', 10), fg='white', bg='red', command=lambda x=theLB:x.delete(ACTIVE)).pack



root.title('Listbox组件教学示例')



mainloop()

------------------------------

【我的问题】

1、上面代码中红色部分,不太理解为何要用到lambda表达式?

2、如果直接用command=theLB.delete(ACTIVE),我试着替换过发现好像不行,无法删除指定选项,而且4个选项变成3个选项

请大神帮忙解疑释惑系下。

ba21 发表于 2022-5-16 23:58:11

command = 函数   # 不会立即执行 (地址)
command = 函数()#代码运行即执行

lambda 是匿名函数,提供的的是个地址
from tkinter import *


root = Tk()




theLB = Listbox(root)
theLB.pack()



for item in ['鸡蛋', '鸭蛋', '鹅蛋', '李狗蛋']:
    theLB.insert(END, item)

def test():
    theLB.delete(ACTIVE)


Button(root, text='删除它', width=10, font=('华康少女文字 - Kelvin', 10), fg='white', bg='red', command=test).pack()



root.title('Listbox组件教学示例')



mainloop()

lzb1001 发表于 2022-5-17 00:10:16

ba21 发表于 2022-5-16 23:58
command = 函数   # 不会立即执行 (地址)
command = 函数()#代码运行即执行



还是没理解呢……

Twilight6 发表于 2022-5-17 07:58:12



上面代码中红色部分,不太理解为何要用到lambda表达式?

因为用 lambda 表达式可以解决传入参数问题,不使用 lambda 表达式只能将 command 赋值为一个函数体,而无法传入参数

如果直接用command=theLB.delete(ACTIVE),我试着替换过发现好像不行,无法删除指定选项,而且4个选项变成3个选项

因为 command 需要接收的是一个函数体,而你这里 theLB.delete(ACTIVE) 属于调用了函数,会将返回结果赋值给 command

此时做出反应的函数就没有效果了(除非你调用的方法返回的还是一个函数体,否则就无法调用)


lzb1001 发表于 2022-5-17 08:50:19

本帖最后由 lzb1001 于 2022-5-17 09:36 编辑

Twilight6 发表于 2022-5-17 07:58
因为用 lambda 表达式可以解决传入参数问题,不使用 lambda 表达式只能将 command 赋值为一个函数 ...

那为什么替换成command=theLB.delete(ACTIVE)运行的话,四个选项会少了第一个“鸡蛋”呢?

用了lambda,结果如下图:


直接用command=theLB.delete(ACTIVE),结果如下图:

Twilight6 发表于 2022-5-17 08:55:20

lzb1001 发表于 2022-5-17 08:50
那为什么替换成command=theLB.delete(ACTIVE)运行的话,四个选项会少了一个呢?

用了lambda,结果如 ...



认真看回复哦:"因为 command 需要接收的是一个函数体,而你这里 theLB.delete(ACTIVE) 属于调用了函数" 你一开始就调用了一次函数,不就将最后一个按钮删除了么

lzb1001 发表于 2022-5-17 09:33:22

本帖最后由 lzb1001 于 2022-5-17 09:34 编辑

ba21 发表于 2022-5-16 23:58
command = 函数   # 不会立即执行 (地址)
command = 函数()#代码运行即执行



theLB = Listbox(root, selectmode=EXTENDED)

即使设置selectmode=EXTENDED多选,但实际也只能删除选中的项目中的最后一个被选中的选项(注意:不是从上往下数的最后一项)

那如何实现多选多删呢???

lzb1001 发表于 2022-5-17 09:35:56

本帖最后由 lzb1001 于 2022-5-17 09:40 编辑

Twilight6 发表于 2022-5-17 08:55
认真看回复哦:"因为 command 需要接收的是一个函数体,而你这里 theLB.delete(ACTIVE) 属于调用了 ...

删除的是“鸡蛋”,它是第一个选项哦

所以它是从上往下删?

Twilight6 发表于 2022-5-17 10:05:16

lzb1001 发表于 2022-5-17 09:35
删除的是“鸡蛋”,它是第一个选项哦

所以它是从上往下删?


嗯,我忘记从哪开始删了,但是原理是一致,从上删一个也是因为你直接赋值 theLB.delete(ACTIVE) 导致的

多选删除实现:

from tkinter import *


root = Tk()




theLB = Listbox(root,selectmode=EXTENDED)
theLB.pack()



for item in ['鸡蛋', '鸭蛋', '鹅蛋', '李狗蛋']:
    theLB.insert(END, item)

def test():
    for i in theLB.curselection()[::-1]:
      theLB.delete(i)


Button(root, text='删除它', width=10, font=('华康少女文字 - Kelvin', 10), fg='white', bg='red', command=test).pack()



root.title('Listbox组件教学示例')



mainloop()

lzb1001 发表于 2022-5-17 11:47:58

Twilight6 发表于 2022-5-17 10:05
嗯,我忘记从哪开始删了,但是原理是一致,从上删一个也是因为你直接赋值 theLB.delete(ACTIVE) 导致的 ...

感谢,测试了可以批量删除

但不明白为何用[::-1]?这个好像是一个反转的列表,我刚测试用[::]的话不行

Twilight6 发表于 2022-5-17 11:49:10

lzb1001 发表于 2022-5-17 11:47
感谢,测试了可以批量删除

但不明白为何用[::-1]?这个好像是一个反转的列表,我刚测试用[::]的话不行


删除前面元素会导致索引发生改变,所以我们倒叙过来删除,就不影响前面元素的索引

lzb1001 发表于 2022-5-17 12:11:15

Twilight6 发表于 2022-5-17 11:49
删除前面元素会导致索引发生改变,所以我们倒叙过来删除,就不影响前面元素的索引

谢谢,还真没想到这点……
页: [1]
查看完整版本: listbox中lambda表达式的使用