我在Windows上使用Python 3.4.1,如果这应该有用。
Q1:如何暂时禁用跟踪变量 我有一个跟踪的变量字段,我想暂时禁用跟踪,以便我可以更改字段的值而不触发对跟踪功能的调用。
有意义吗?
可能是我做错了(我加入了一段代码):
我有一个下拉列表,显示了我可以选择的项目列表。 我有第二个下拉列表,为第一个下拉菜单中的每个项目显示“子项目”列表,当我更改第一个下拉菜单时,必须更新这些项目。
Q2:问题是,当第一个下拉菜单更改后,如何“重新包装”第二个下拉菜单?
以下是代码:
import tkinter as tk
WORKINGWINDOWWIDTH = 800 # Width for the working window
WORKINGWINDOWHEIGHT = 800 # Height for the working window
root = tk.Tk()
w = tk.Canvas(root, width=WORKINGWINDOWWIDTH - 10, height=WORKINGWINDOWHEIGHT - 10, bg="darkred")
def display_parameters(*args):
print("args: {0}, and I have the following option: {1}".format(args, functionChoiceVar.get()))
if functionChoiceVar.get() == "Option 1":
print("I picked the first one...")
print("How do I repack the presets?")
elif functionChoiceVar.get() == "Option 2":
print("I picked the second one...")
return
def display_options(*args):
print("args: {0}, and I have the following suboption: {1}".format(args, presetChoiceVar.get()))
return
functionChoiceVar = tk.StringVar(root)
functionChoices = ['Option 1', 'Option 2']
functionOption = tk.OptionMenu(root, functionChoiceVar, *functionChoices)
functionOption.pack(side='left', padx=10, pady=10)
functionOption.place(x= 10, y=10)
functionChoiceVar.set('Option 1')
functionChoiceVar.trace("w", display_parameters)
presetChoiceVar = tk.StringVar(root)
presetChoices11 = ['Suboption 11', 'Suboption 12', 'Suboption 13', 'Suboption 14','Suboption 15']
presetChoices12 = ['Suboption 21', 'Suboption 22', 'Suboption 23', 'Suboption 24','Suboption 25']
presetOption = tk.OptionMenu(root, presetChoiceVar, *presetChoices11)
presetOption.pack(side='left', padx=10, pady=10)
presetOption.place(x= 100, y=10)
presetChoiceVar.set('Suboption 11')
presetChoiceVar.trace("w", display_options)
答案 0 :(得分:5)
设置跟踪时,tkinter将返回一个id,您可以使用该ID在以后使用.trace_vdelete()
方法删除跟踪。要重新启动跟踪,只需执行您第一次执行的操作。
跟踪跟踪ID的一种简单方法是将其作为属性存储在StringVar
的实例中。
例如:
functionChoiceVar.trace_id = functionChoiceVar.trace("w", display_parameters)
...
functionChoiceVar.trace_vdelete("w", functionChoiceVar.trace_id)
(顺便说一下,与问题无关,调用.pack()
然后立即调用.place()
没有任何意义。您可以删除对.pack()
的调用,因为它被否定了致电.place()
)
答案 1 :(得分:2)
aWriteTracerID = presetChoiceVar.trace( "w", aWriteHANDLER ) # SAVE <<aTracer>> ID#
# setup code continues
presetChoiceVar.trace_vdelete( "w", aWriteTracerID ) # REMOVE <<aTracer>>
# code
# that needs the write-tracer
# to have been removed
# ...
aWriteTracerID = presetChoiceVar.trace( "w", aWriteHANDLER ) # SET AGAIN
答案 2 :(得分:1)
删除痕迹最简单的方法是说:
idx = 0 # This is the index of the first trace on tk_variable.
tk_variable.trace_remove(*tk_variable.trace_info()[idx])
要添加回溯,您可以说:
tk_variable.trace_add('write', your_function)
要检查是否跟踪了一个变量,您可以说:
if tk_variable.trace_info():
# do something
pass
答案 3 :(得分:0)
我在创建一个新类时自己遇到了这个类,该类继承了一个以变量作为输入关键字参数的基类。所以我开发了下面的例程,它尝试从globals()恢复一个命名的回调函数,这是基于Trace ID只是原始回调函数名前面的一些数字这一事实。我希望那些数字有一些含义,但我无法确定它们。这是例程:
def get_observer_callback(id):
func = None
funcname = id.lstrip('0123456789')
if funcname != '<lambda>' and funcname in globals():
func = globals().get(funcname)
if type(func) is not type(lambda:()):
func = None
return func
测试时,trace_id 50360848my_callback ,回调函数被识别为
<function my_callback at 0x03064370>
有趣的是,来自包装器的50360848是十六进制0x03007210,它与函数描述中的十六进制0x03064370在同一个球场中。除了那之外,我找不到两者之间的硬关系...... 我将上述例程描述为kludge,但是,考虑到Tk实现,上述kludge足以用于命名函数。显然,它对lambda函数没有帮助。我希望在Tk中有一个注册表,它包含所有需要的信息,包括对函数对象的引用。理想情况下,从Tk内部表中返回函数对象的调用最好。欢迎任何意见。