pythontkintertkinter-entryttk

How do you get the StringVar (not the text value, the StringVar itself) of an Entry?


I'm trying to get the StringVar object associated with an Entry widget, but I can't figure out how.

I found this question: get StringVar bound to Entry widget but none of the answers work for me. Both entry["textvariable"] and entry.cget("textvariable") return the name of the StringVar and not the StringVar itself (although the answer with the second explains it properly, unlike the answer with the first which is NOT clear that it only returns the name. I've submitted an edit for the first that fixes this). You're supposed to be able to get the StringVar from its name using entry.getvar(name), but this is returning a str with the contents of the StringVar instead of the StringVar itself. I don't understand why this is happening, because the answer that explains this is marked as correct, and the person who asked the question seems to have wanted the StringVar itself. Did something get changed? If so, how would I get the StringVar now? I'm using Python 3.11.9 at the moment. I would also prefer a method that doesn't need the name of the StringVar, as an Entry without a StringVar explicitly set seems to have a StringVar without a name.

Here is some example code:

from tkinter import *
from tkinter.ttk import *

root = Tk()

stringVar = StringVar(root, "test") # obviously in the real program I wouldn't be able to access this without using the Entry
entry = Entry(root, textvariable=stringVar)
entry.pack()

name1 = entry["textvariable"]
name2 = entry.cget("textvariable")
print(name1 == name2) # True

shouldBeStringVar = entry.getvar(name1)

print(name1, type(name1)) # PY_VAR0 <class 'str'>
print(shouldBeStringVar, type(shouldBeStringVar)) # test <class 'str'>

Solution

  • If you know the name of the variable, you can simply "create" a StringVar and set its parameter "name" to that name. This way you will simply get the variable you created earlier. So try this:

    ...
    string_name = entry["textvariable"]
    TheVarObjectYouNeed = var = tk.StringVar(name=string_name)
    print(f"The var {var} has a type {type(var)}, just as you wanted")
    print(f'And it has the value "{var.get()}"')
    ...
    

    Note that this code actually creates a new StringVar object. But since I set it to an existing name, "TheVarObjectYouNeed" will actually refer to the same internal variable inside the underlying TCL interpreter (as correctly stated in the comment below), same TCL variable is used for your Entry widget.