当 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(...)
但它是在一行中完成的。
我正在学习使用 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(...)
但它是在一行中完成的。