Python 3如何暂时禁用跟踪变量

时间:2014-10-07 14:08:00

标签: python tkinter

我在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)

4 个答案:

答案 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)

A1:如何暂时删除跟踪&之后返回

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内部表中返回函数对象的调用最好。欢迎任何意见。