当 ttk.Checkbox() 值改变时如何 运行 编码 (python)?

How to run code when ttk.Checkbox() value changes (python)?

我正在学习使用 tkinter/ttk(在 GUI 编程方面我仍然是个菜鸟)并且我遇到了一个我无法完全理解的问题。

我想做的是创建一个程序,为用户提供多个复选框,并根据用户检查的内容,从互联网上获取一些数据。我制作了几个用于测试的复选框,并将它们全部绑定到同一个函数中。

我遇到的问题是,虽然 this source 声称在 ttk.Checkbox 中使用 command 选项时,函数将被调用 每次复选框的状态改变(我假设改变= tick/untick),我只是没有看到它发生(可能只是我没有正确理解它)。我将复制粘贴我正在尝试 运行 的代码(我删除了格式、图像等以使其更小更简单):我正在使用 Python v3.4.2 和 Tcl/Tk v8.6)

from tkinter import *
from tkinter import ttk

nimekiri = []

def specChoice(x):
    choice = wtf[x].get()
    print("step 1") #temp check 1 (to see from console if and when the program reaches this point)
    if len(choice) != 0:
        print("step 2") #temp check 2
        spec = choice.split(" ")[0]
        tic = choice.split(" ")[1]
        if tic == "yes":
            print("step 3") #temp check 3
            nimekiri.append(spec)
        elif tic == "no":
            if spec == nimekiri[x].get():
                nimekiri.remove(spec)

    
root = Tk()
# Frames
mainframe = ttk.Frame(root, padding="3 3 12 12")
mainframe.grid(column=0, row=0, sticky=(N, W, E, S))

spec_frame = ttk.Labelframe(root, text="Placeholder for txt: ", padding="9 9 12 12")
spec_frame.grid(column=0, row=0, sticky=(N, W, E, S))

results_frame = ttk.Labelframe(root, text="Results: ", padding="3 3 12 12")
results_frame.grid(column=10, row = 0, sticky=(N, W, E, S))

# Text Labels
ttk.Label(spec_frame, text="Question:").grid(column=1, row=1, sticky=(N,S,W))
ttk.Label(spec_frame, text="Choice 1").grid(column=1, row=2, sticky=(N,S,W))
ttk.Label(spec_frame, text="Choice 2").grid(column=1, row=3, sticky=(N,S,W))

# Checkboxes etc
results_window = Text(results_frame, state="disabled", width=44, height = 48, wrap="none")
results_window.grid(column=10, row=1, sticky=W)

wtf = []
wtf.append(StringVar())
wtf.append(StringVar())
wtf[0].set("choice1 no")
wtf[0].set("choice2 no")
ttk.Checkbutton(spec_frame, command=specChoice(0), variable=wtf[0],
                onvalue="choice1 yes", offvalue="choice1 no").grid(column=0, row=2, sticky=E)
ttk.Checkbutton(spec_frame, command=specChoice(1), variable=wtf[1],
                onvalue="choice2 yes", offvalue="choice2 no").grid(column=0, row=3, sticky=E)


#wtf[0].trace("w", specChoice2(0))

root.mainloop()

在上面的代码中,我期望发生的是当用户选择 Choice 1 框时,wtf[0] 的值将被更改并且 specChoice(0) 函数将是 运行,但是随着我添加的 print() 函数似乎在我启动程序时 specChoice 只是 运行,因此程序永远不会达到 #temp check 3。(在我添加默认值之前它甚至没有达到 #temp check 2复选框变量的值)

当您使用 command=specChoice(0) 时,您将调用 specChoice(0) 的 return 值分配给命令,即 None。您需要将函数传递给命令,而不是函数调用,例如 command=specChoice.
但是,这种方式不能传递函数参数。为了克服这个问题,您可以创建一个调用 specChoice(0) 的匿名函数,例如:

ttk.Checkbutton(spec_frame, command = lambda: specChoice(0), ...).grid(...)

这基本上是在做:

def anonymous_function_0():
    specChoice(0)

ttk.Checkbutton(spec_frame, command=anonymous_function_0, ...).grid(...)

但它是在一行中完成的。