【问题标题】:Lambda function in for loop to bind keywords in tkinterfor循环中的Lambda函数在tkinter中绑定关键字
【发布时间】:2020-08-27 06:44:09
【问题描述】:

我对 Python 和 tkinter 非常陌生。我正在使用 tkinter 开发键盘。我创建了一个文本框,我正在尝试将键绑定到它,以便用户可以使用键盘进行输入。我想在按下一个键时打印不同的键。例如,我想在按下“p”时打印 P,当按下“a”时打印 A。我知道我可以手动输入每个键并添加一个函数来打印所需的值,但这会很耗时,所以我决定使用字典。

下面是这个的代码。

def print_letter(letter):
    if letter == "backspace":
        text.configure(state="normal")
        value = text.get("1.0", "end")
        text.delete("1.0", "end")
        text.insert("1.0", value[:-2])
        text.configure(state="disabled")
    else:        
        text.configure(state="normal")
        text.insert("end", letter)
        text.configure(state="disabled")

    letters = {
        'a': 'A',
        'b': 'B',
        'c': 'C',
        'd': 'D',
        'e': 'E',
    }

    root = tk.Tk()
    root.geometry("800x415")
    root.resizable(False, False)

    text = tk.Text(text_frame, width=97, height=15)
    text.configure(state="disabled")
    text.grid(row=0, column=0, sticky="EW")
    text.focus_set()

    for key, value in letters.items():
        text.bind(key, lambda value: print_letter(letters.get(key)))

但只有字典中的最后一个值绑定到我按下的任何键。我在 SO 上看到了一些帖子,他们都建议了以下选项:

  1. text.bind(key, lambda value=value: print_letter(letters.get(key)))
  2. text.bind(key, lambda args=value: print_letter(letters.get(key)))

以上所有都给了我相同的结果。

感谢任何帮助。

【问题讨论】:

    标签: python-3.x tkinter lambda


    【解决方案1】:

    我个人的偏好是使用functools.partial 而不是lambda,因为它会冻结参数。这是一个实践中的例子。

    import tkinter as tk
    from functools import partial
    
    # here we add an *args argument 
    # since tkinter will also send the keystroke
    # as an argument
    def print_letter(letter, *args):
        if letter == "backspace":
            text.configure(state="normal")
            value = text.get("1.0", "end")
            text.delete("1.0", "end")
            text.insert("1.0", value[:-2])
            text.configure(state="disabled")
        else:      
            text.configure(state="normal")
            text.insert("end", letter)
            text.configure(state="disabled")
    
    letters = {
        'a': 'A',
        'b': 'B',
        'c': 'C',
        'd': 'D',
        'e': 'E',
    }
    root = tk.Tk()
    root.geometry("800x415")
    root.resizable(False, False)
    text = tk.Text(root, width=97, height=15)
    text.configure(state="disabled")
    text.grid(row=0, column=0, sticky="EW")
    text.focus_set()
    for key, value in letters.items():
        # partial takes unlimited args.
        # The first being the function name 
        # and subsequent ones being the arguments
        text.bind(key, partial(print_letter, value))
    
    root.mainloop()
    

    【讨论】:

    • 成功了!非常感谢。我看到很多帖子,社区在使用 lamda 和 functools.partial 之间存在分歧。再次感谢。
    【解决方案2】:

    如果我正确理解了您的问题,您需要某事。像这样:

    l = []
    
    for _ in range(10):
        l.append(lambda v=_: print(v))
    

    希望对你有帮助!

    【讨论】:

    • 感谢您的评论。所以这将创建一个带有 lambda 函数的列表。如何将键绑定到列表中的各个 lambda 函数?
    • for key, value in letters.items(): text.bind(key, lambda value=key: print_letter(letters.get(value)))
    猜你喜欢
    • 2021-07-23
    • 1970-01-01
    • 2014-04-18
    • 1970-01-01
    • 2012-12-24
    • 2012-05-19
    • 2020-02-04
    • 1970-01-01
    • 2021-06-04
    相关资源
    最近更新 更多