Python 将变量通过lambda传递到函数Tkinter

Python 将变量通过lambda传递到函数Tkinter,python,class,lambda,callback,tkinter,Python,Class,Lambda,Callback,Tkinter,下面代码的问题是通过lambda将“i”(只是一个简单的数字范围,但会根据数字框的不同而变化)传递给callback,以便创建每个框的单独功能 我曾尝试阅读教程并尝试代码中的各种内容,但要么不起作用,要么出现错误“lambda()只需要2个参数,3个给定参数”等等。我相信我需要列出“I”,但我仍然会遇到此特定错误 我已经对出现问题的代码进行了评论。我需要返回每个框中的值并覆盖文本 多谢各位 self.clicked = [] # In my __init__ definition self.nu

下面代码的问题是通过lambda将“i”(只是一个简单的数字范围,但会根据数字框的不同而变化)传递给callback,以便创建每个框的单独功能

我曾尝试阅读教程并尝试代码中的各种内容,但要么不起作用,要么出现错误“lambda()只需要2个参数,3个给定参数”等等。我相信我需要列出“I”,但我仍然会遇到此特定错误

我已经对出现问题的代码进行了评论。我需要返回每个框中的值并覆盖文本

多谢各位

self.clicked = [] # In my __init__ definition
self.numbers = [StringVar() for i in xrange(self.number_boxes) ]   # Create Stringvar for each box

for i in xrange(self.number_boxes): # For each number, create a box

        self.clicked.append(False) # Not clicked in yet
        self.box.append(Entry(self.frame_table,bg='white',borderwidth=0, width=10, justify="center", textvariable=self.numbers[i], fg='grey')) # Textvariable where I enter a value to get after, need to do for each box (use box[i] but cannot for append)
        self.box[i].grid(row=row_list,column=column+i, sticky='nsew', padx=1, pady=1) 
        self.box[i].insert(0, "Value %g" % float(i+1))
        self.box[i].bind("<Button-1>", lambda event, index=i : self.callback(event, index)) # Need to pass the 'i's' to callback but having lambda difficulties

for i in self.numbers: 
        i.trace('w',lambda index=i: self.numberwritten(index) ) # Need for each box again here

def numberwritten(self, index): # A way of combining numberwritten and callback?
    po = self.box[index].get() # Get the values in each box
    print po

def callback(self, event, index):
        if (self.clicked[index] == False): # When clicked in box, overwrite default text with value and change colour to black, not grey
            self.box[index].delete(0, END)
            self.box[index].config(fg='black')
                self.clicked[index] = True
已更新: 看来你的lambda真是太棒了。把它全部去掉

尝试:


更新:

当我输入我的答案时,你似乎让情况更糟了,也许吧 对lambda习语的一点澄清将比我的解决方案更能帮助您 以上.-)

lambda函数也称为匿名函数,因为它们不需要 有名字

比较以下示例:

>>>ulist = 'a1 s3 d2 f4 k6 w9'.split()

def normal_sort(L,R):
    result = int(L[1]) - int(R[1])
    return result

>>> sorted(ulist, normal_sort)
['a1', 'd2', 's3', 'f4', 'k6', 'w9']
与lambda函数相同:

sorted(ulist, lambda L, R: int(L[1])-int(R[1]))
['a1', 'd2', 's3', 'f4', 'k6', 'w9']
lambda函数具有

  • 没有名字
  • 无参数括号
  • 没有返回语句,因为对它的单个语句的求值会作为返回值传回
  • 您可以通过将lambda函数指定给名称来命名该函数:

    lambda_sort = lambda L, R: int(L[1])-int(R[1])
    

    但是,切换到正常功能可能已经很有用了。

    您的代码非常接近,但是这一行:

    self.box[i].bind("<Button-1>", lambda self, event,i : self.callback(event, data))
    

    我不明白第行
    po=box[I].get()
    :它不应该是
    po=self.box[I].get()
    ?我不明白lambda I:self.numberwrited(n)的意思:
    n
    来自哪里?是的,对不起,我用的是旧版本的代码。代码编辑。粘贴完整的回溯我不确定你的意思,我已经包含了所有与NumberWrited函数链接的内容。你真正想实现的是什么?每次更改每个条目时,您真的需要回调吗?为了什么?是否用于输入验证?如果是这样的话,有更好的方法在条目小部件上进行输入验证。这不起作用,它仍然会给我参数数量上的错误。感谢更新(我使用了一个我发现的示例,试图让我的代码清晰,显然不是!)。然而,它仍然似乎不起作用,它真的让我困惑!我已将代码更改回。。!我不知道StringVar.trace应该有哪些参数和多少个参数,但我的猜测是:一个参数和这个参数应该是一个字符串,或者至少是可以转换为字符串的某个参数,因此在那里终止lambda构造also@DonQuestion:跟踪回调采用3个参数:、name1、name2和op。第一个是变量的名称,第二个是变量的索引,如果它是数组(我认为tkinter不支持),第三个是“读”、“写”或“未设置”,这取决于调用回调的事件。啊,好吧-我不是一个生动的tcl/tk用户-这整个“一切都是一个字符串”这项工作并不吸引我,但问题是我的循环,因为索引必须是一个列表才能包含所有i no的值?我也不明白我怎么能做一个列表,因为它不是数字列表。很抱歉,我对这些东西这么不熟悉!Clicked是一个bool对象,不能使用append。我正在努力获取回调函数的最后几点,并对代码进行分类。请更新当前的代码。只能将index=0传递给callback,但仍不知道是否可以合并numberwrited和callback以写入和读取框中的值?关于列表-它们可以包含您想要的任何类型,因此只需使用
    clicked=[]
    创建空列表,然后使用
    clicked.append(False)
    。您可以使用:
    self.clicked=[False]*len(self.box)
    如果不是self.clicked[index]:
    语法。
    sorted(ulist, lambda L, R: int(L[1])-int(R[1]))
    ['a1', 'd2', 's3', 'f4', 'k6', 'w9']
    
    lambda_sort = lambda L, R: int(L[1])-int(R[1])
    
    self.box[i].bind("<Button-1>", lambda self, event,i : self.callback(event, data))
    
    self.box[i].bind("<Button-1>", lambda event, index=i: self.callback(event, index))
    
    # Create an empty list based on the number of boxes created 
    # above. This could go in your class's __init__ function, 
    # or it could be declared globally, depending on the scope
    # of self.box and the loop which determines its length.
    self.clicked = ([False] * len(self.box))
    
    # Finally, in your callback, check one member of the list,
    # depending on which box was clicked.
    def cb(self, event, index):
        if not self.clicked[index]:
            self.box[index].delete(0, END)
            self.box[index].config(fg='black')
            self.clicked[index] = True
        # Print the value of each of the widgets stored in the box list.
        for i, j in enumerate(self.box):
            print("%ith element: %s" % (i, j.get()))