Python 3 How to temporarily disable trace variables

I am using Python 3.4.1 for windows, if that helps.

Q1: How to temporarily disable tracing variables I have a traceable variable field and I would like to temporarily disable tracing so that I can change the value of the field without calling the trace function.

Does it make sense?

And it is possible that I am doing it all wrong (and I am attaching to the code snippet):

I have a dropdown that shows a list of items that I can select. I have a second dropdown that shows, for each of the items in the first dropdown, a list of "subitems", which of course must be updated when the first dropdown changes.

Q2: The question is, how do I "repackage" the second dropdown on the first change?

Here is the code:

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)

      

+3


source to share


3 answers


When you set up a trace, tkinter will return an identifier that you can use to remove the trace later using the method .trace_vdelete()

. To restart tracing, simply follow what you did the first time.

An easy way to keep track of the trace ID is to store it as an attribute on the right of the instance StringVar

.

For example:



functionChoiceVar.trace_id = functionChoiceVar.trace("w", display_parameters)
...
functionChoiceVar.trace_vdelete("w", functionChoiceVar.trace_id)

      

(by the way, unrelated to the request calling .pack()

and then calling immediately .place()

has no purpose. You can delete the call .pack()

because it is dropped by the call .place()

)

+5


source


A1: how to temporarily remove the trace and return it after



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


source


I ran into this myself while creating a new class that inherits from the base class, taking a variable as a keyword argument. So I developed a subroutine below that tries to reconstruct a named callback function from global variables () based on the fact that the trace ID is nothing more than some numeric digits preceding the original name of the callback function. I expect these numbers to make some sense, but I have not been able to establish them. Here's the procedure:

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

      

During testing, the trace_id was 50360848my_callback and the callback function was identified as

  <function my_callback at 0x03064370>

      

Interestingly, the 50360848 from the wrapper is hex 0x03007210, which is in the same ball as hex 0x03064370 from the function description. I couldn't find any difficult relationship between them outside of that ... I would describe the above procedure as a kludge, but perhaps given the Tk implementation, the above kludge is sufficient for named functions. Obviously this is not useful for lambda functions. I expect that Tk has a registration table that contains all the information you need, including references to function objects. Ideally, a call that returns a function object from the Tk internal table would be better. Any input is appreciated.

0


source







All Articles