我有一个使用Tkinter的程序,该程序使用多个StringVar
来跟踪多个窗口上的数据。我一直在使用
myStringVar.trace('w', lambda *args: update())
检测用户何时更改其中一个变量,通过与条目交互或从OptionMenu
中选择选项,其中'update'是一个根据需要更改GUI的其他部分的函数和'root '是的。但是,我发现update()
在我的代码的特定行中被myStringVar.trace()
调用:
name = OptionMenu(self, self.source, self.source.get(), *root.namelist)
其中self.source
是有问题的StringVariable
,root.namelist
是普通的列表。我通过将上面的行夹在两个跟踪语句之间并将trace语句添加到我的更新函数中来发现这一点。我还确认用
name = Entry(self, textvariable=self.source)
不会有相同的结果。
尽可能多地复制原始代码的形式,我编写了以下测试代码:
from tkinter import *
root = Tk()
root.myStringVar = StringVar(root)
root.myStringVar.set('hello')
class myFrame(Frame):
def __init__(self, root):
Frame.__init__(self, root)
self.source = root.myStringVar
self.update()
self.pack()
def update(self):
for widget in self.winfo_children(): widget.destroy()
name = OptionMenu(self, self.source, self.source.get(), '1','2','3')
name.pack()
root.myframe = myFrame(root)
root.myStringVar.get()
def speak(root):
print(root.myStringVar.get())
root.myframe.update()
root.myStringVar.trace('w', lambda *args: speak(root))
mainloop()
但是,当我运行此代码时,除非我按照您的预期更改OptionMenu
中的选项,否则它不会打印任何内容。
我能想到的两种情况之间的唯一区别是,在我的测试代码中,放置OptionMenu
的帧是静态的,而在我的实际代码中它是动态生成的,但我看不到这将如何影响处理OptionMenu
的创建方式。
答案 0 :(得分:0)
要回答您的特定问题“当StringVar添加到窗口小部件时,TKinter-是StringVar.trace吗?”,答案是“否”。将stringvar添加到窗口小部件时,不会调用跟踪。跟踪 - 假设它是写跟踪 - 仅在变量值更改时调用。
问题可能是由于您正在创建名为update
的方法。这是一种已存在于小部件上的方法,可能由各种tkinter函数在内部调用。尝试将您的函数重命名为其他内容(例如:update_widget
)。
答案 1 :(得分:0)
[...]
root.myframe = myFrame(root)
#this print myStringVar content even when the value doesn't change (each time you call it):
print("main:", root.myStringVar.get()) #<-- this is the missing print, i guess
def foo(*args): #custom useless function
"""Prints "hello" each time OptionMenu selection change"""
print("foo: hello")
def showargs(*args): #show params, useless too
"""Prints args content each time OptionMenu change"""
print("showargs:", args)
def showcontent(*args): #finally this print myStringVar content
"""Prints myStringVar content each time OptionMenu change"""
print("showcontent: ",root.myStringVar.get())
root.myStringVar.trace('w', foo)
root.myStringVar.trace('w', showargs)
root.myStringVar.trace('w', showcontent)
#output:
#main: hello
#after user select "1" from OptionMenu:
#showcontent: 1
#showargs: ('PY_VAR0', '', 'w')
#foo: hello
我添加了三个调试方法来测试myStringVar内容:
foo没用,但每次用户更改OptionMenu值时都会触发,
showargs显示* args param内容,
showcontent显示myStringVar内容。
如果你因为第19行而被卡住了,你会忘记将它打印到控制台或以某种方式显示gui(我添加了一个打印件)并且它有效。
因此,您可以传递myStringVar并获取其内容和/或显示对其的任何更改。