1

Below is some code that I'm testing with. In this code, I am able to create a window and have a Label on top and a Entry field on bottom. When I type in that entry field, I can dynamically change what's in the label. Now, I have included a function that is trying to evaluate a variable assigned to "tex", by storing what is predefined in the Entry widget. Which is "cat". This is picked up by:

tex = e.get()

I understand that get() is not changing dynamically as I change the text in the entry widget. So it cannot change to "dog" when I change the string in the entry widget. Is this possible? Here is the code:

from Tkinter import *
import time

root = Tk()

def change():   
    if tex  == ("cat"):
        time.sleep(0.5)
        pass
    else:
        time.sleep(0.5)
        e.delete(0, END)
        e.insert(0, "dog")

v = StringVar()

e = Entry(root, textvariable=v)
e.insert(0, "cat")
e.pack(side=BOTTOM)
tex = e.get() #When text is defined with get(), it does not change 
              #dynamically with the entry widget


l = Label(root, textvariable=v)
l.pack(side=TOP)

change()

root.mainloop()

Any help would be appreciated.

  • You are creating the `StringVar` incorrectly. It needs to be `v = StringVar()` (note the trailing `()`) – Bryan Oakley Jan 26 '17 at 14:14
  • I don't see the point of what you want to achieve. The StringVar `v` is here to change dynamically when the Entry content changes, so why do you need another variable that changes dynamically too? – j_4321 Jan 26 '17 at 14:17
  • I'm not trying to achieve nothing. It's just an exercise, more or less. I'm trying to see if it is possible to effect the entry string to trigger the condition loop to change the label widget "on the fly" once I effect the string "cat". In other words, I expect that when I start to backspace and remove the "t" from cat, the entry and widget gets changed instantly. – Jason Woodruff Jan 26 '17 at 14:26
  • @Byran Oakley - With or without () at the end of StringVar, the program still works, weirdly enough. But I appreciate you noting that for me. I will update the code to reflect the correct formatting. – Jason Woodruff Jan 26 '17 at 14:29
  • It works without the `()` only by accident as a side effect of how its implemented. If you had two stringvars created this way, they would both share the same data. – Bryan Oakley Jan 26 '17 at 15:19

1 Answers1

3

To answer your specific question, no, there is no way for tex to magically keep updated when the entry widget changes. That feature is exactly why the textvariable attribute exists -- it causes the variable to always be updated with the value in the entry widget. If you need the data in another variable, you will have to call the .get() method.

That being said, you can set a trace on the variable, or a binding on the entry widget, and have it call code that can update tex to whatever you want when the entry widget changes.

For example, the following code shows how to have callback called whenever the value in the entry widget changes:

def callback(*args):
    global tex
    tex = e.get()
v.trace("w", callback)

For more information about what arguments are passed to the callback, see What are the arguments to Tkinter variable trace method callbacks?

All that being said, you have a couple of critical flaws in your code. First, you are creating the StringVar incorrectly. It needs to be v = StringVar() (note the trailing ()).

Also, you should never call sleep in the main thread of a GUI program. Read up on the after method if you want to execute some code after some time has elapsed.

Community
  • 1
  • 1
Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685