如何针对Combobox的每次更改将函数唯一地绑定到Ttk Combobox

时间:2019-10-10 16:54:07

标签: python tkinter ttk

我想将一对组合框唯一地链接起来,例如,一个组合框中的值取决于另一个组合框中的当前值。 但我无法使其正常工作。仅一个组合框的初始值会影响另一个组合框的值。 :我希望在组合框值的每次更改时都调用该函数。

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()

我希望结果显示为(1,2)在cmb1中的Option1在cmb2中,(3,4)在cmb1中的Option2在cmb2中 对于cmb3中的Option3,以cmb4为(5,6),依此类推。

2 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分:0)

  

好吧,我刚刚尝试用lambda抛出命令:但是随后我得到一个错误,取0 ....但是给出了1,所以我只是在lambda函数中添加了一个参数作为lambda x:即,该代码现在可以完美运行,但是即使我可以运行它,但是我仍然不完全了解它是如何解决的

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

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()