如何将函数绑定到Ttk Combobox,以便为组合框的值的每个变化唯一地绑定



我想唯一地链接一对组合框,例如组合框中的值取决于另一个组合框中的当前值。 但我没能让它工作。只有一个组合框中的初始值对另一个组合框中的值有影响。我希望为组合框值的每次更改调用该函数。

import tkinter as tk
from tkinter import ttk
class Win(tk.Tk):
opt_dic1 = {'Option1' : ['1', '2'], 'Option2' : ['3', '4']}
opt_dic2 = {'Option3' : ['5', '6'], 'Option4' : ['7', '8']}
def __init__(self):
super().__init__()
top = tk.Frame(self)
btm = tk.Frame(self)
cmb1 = ttk.Combobox(top, values = list(Win.opt_dic1.keys()))
cmb2 = ttk.Combobox(top)
cmb3 = ttk.Combobox(btm, values = list(Win.opt_dic2.keys()))
cmb4 = ttk.Combobox(btm)
top.pack(side = 'top')
btm.pack(side = 'bottom')
cmb1.pack(side = 'left')
cmb2.pack(side = 'left')
cmb3.pack(side = 'left')
cmb4.pack(side = 'left')
cmb1.current(0)
cmb3.current(0)
cmb1.bind('<<ComboboxSelected>>', cmb2.config(values = Win.opt_dic1[cmb1.get()]))
cmb3.bind('<<ComboboxSelected>>', cmb4.config(values = Win.opt_dic2[cmb3.get()]))
if __name__ == '__main__':
Win().mainloop()

我预计 cmb2 中选项1的结果为 (1,2(,cmb1 中选项 2 的结果为 (3,4( cmb2 中的选项 1 和 (5,6( 在 cmb4 中用于 cmb3 中的选项 3,依此类推。

好吧,我只是尝试使用 lambda 抛出命令:但后来我得到一个错误需要 0 ....但是给出了 1,所以我只是在 lambda 函数中添加一个参数作为 lambda x:现在我得到了相同的预期结果,即代码现在运行良好,但即使我已经让它工作,但我仍然不完全理解它是如何解决的

您的lambda正在由bind()发送事件。这就是你的错误的来源。通过向 lambda 添加x,通过允许一个位置参数来处理事件。如果没有格式正确的 lambda,您的代码无法工作的原因是具有括号cmb2.config()和其他配置。当您将某些命令/函数分配给bind()时,您需要保存对命令/函数的引用,而不是调用它。这是通过不使用括号来完成的,但同时您不能传递参数。这就是 lambda 允许的。

λ示例:

import tkinter as tk
from tkinter import ttk

class Win(tk.Tk):
opt_dic1 = {'Option1': ['1', '2'], 'Option2': ['3', '4']}
opt_dic2 = {'Option3': ['5', '6'], 'Option4': ['7', '8']}
def __init__(self):
super().__init__()
top = tk.Frame(self)
btm = tk.Frame(self)
cmb1 = ttk.Combobox(top, values=list(Win.opt_dic1.keys()))
cmb2 = ttk.Combobox(top)
cmb3 = ttk.Combobox(btm, values=list(Win.opt_dic2.keys()))
cmb4 = ttk.Combobox(btm)
top.pack(side='top')
btm.pack(side='bottom')
cmb1.pack(side='left')
cmb2.pack(side='left')
cmb3.pack(side='left')
cmb4.pack(side='left')
cmb1.current(0)
cmb3.current(0)
cmb1.bind('<<ComboboxSelected>>', lambda x: cmb2.config(values=Win.opt_dic1[cmb1.get()]))
cmb3.bind('<<ComboboxSelected>>', lambda x: cmb4.config(values=Win.opt_dic2[cmb3.get()]))

if __name__ == '__main__':
Win().mainloop()

没有 lambda 的示例:

import tkinter as tk
from tkinter import ttk

class Win(tk.Tk):
opt_dic1 = {'Option1': ['1', '2'], 'Option2': ['3', '4']}
opt_dic2 = {'Option3': ['5', '6'], 'Option4': ['7', '8']}
def __init__(self):
super().__init__()
top = tk.Frame(self)
btm = tk.Frame(self)
self.cmb1 = ttk.Combobox(top, values=list(Win.opt_dic1.keys()))
self.cmb2 = ttk.Combobox(top)
self.cmb3 = ttk.Combobox(btm, values=list(Win.opt_dic2.keys()))
self.cmb4 = ttk.Combobox(btm)
top.pack(side='top')
btm.pack(side='bottom')
self.cmb1.pack(side='left')
self.cmb2.pack(side='left')
self.cmb3.pack(side='left')
self.cmb4.pack(side='left')
self.cmb1.current(0)
self.cmb3.current(0)
self.cmb1.bind('<<ComboboxSelected>>', self.config_cmb2)
self.cmb3.bind('<<ComboboxSelected>>', self.config_cmb4)
def config_cmb2(self, _=None):
self.cmb2.config(values=Win.opt_dic1[self.cmb1.get()])
def config_cmb4(self, _=None):
self.cmb4.config(values=Win.opt_dic2[self.cmb3.get()])

if __name__ == '__main__':
Win().mainloop()

好吧,我只是尝试用lambda:抛出命令,但后来我得到了一个错误<lambda> takes 0 ....but 1 was given所以我只是在lambda函数中添加了一个参数作为lambda x: <function>,现在我得到了相同的预期结果,即,代码现在运行良好,但即使我已经让它工作,但我仍然不完全理解它是如何解决的, 如果有人能解释一下,那将是有帮助的。

最新更新