I have an Entry that updates once via a textvariable set to a StringVar, but then only via manual keypress from user after that.
I'm writing a GUI using model-view-controller pattern.
I have a controller class, that owns the main tk object. It also owns a StringVar(). I've set up a callback to fire when the StringVar is written to.
from Tkinter import *
from tkFileDialog import askopenfilename
class Controller:
def __init__(self):
self.root = Tk()
self.fname = StringVar()
self.fname.trace('w', self.file_name_updated)
self.view = View(self.root, self.fname)
def file_name_updated(self, name, index, mode):
varValue = self.root.globalgetvar(name)
print ('filename updated!!! %s' % varValue)
self.root.globalsetvar(name, 'changing it again!')
def run(self):
self.root.mainloop()
class View:
def __init__(self, tk, fname_var):
self.form = tk
self.fileNameVar = fname_var
self.inFileTxt = Entry(self.form, textvariable=fname_var)
self.inFileTxt.grid(row=1)
self.inFileBtn = Button(self.form, text="Browse ...", command=self.open_file)
self.inFileBtn.grid(row=1, column=8)
def open_file(self):
fname = askopenfilename()
self.fileNameVar.set(fname) # update the updateable text
if __name__ == '__main__':
c = Controller()
c.run()
The controller creates a View instance. The View object, draws an Entry box which assigns the StringVar to its textvariable
attribute.
The View object also has a Button
. When clicked, this sets the value of the StringVar(), and fires the callback.
So far so good. The StringVar
has been set to the chosen filename, the callback fires, I see my debug. But then, in my callback, I update the value of the StringVar
again. It's just a test, ultimately I want to clear the value of the StringVar
if the filename chosen has errors (but that wasn't working, so I'm trying to narrow it down).
Anyway, I'm expecting the text in the entry box to say 'changing it again!'. But I don't see that. It stays the same.
Debug shows that the value of the variable is 'changing it again!', but the Entry box has not updated.
However, when I place the cursor inside the Entry box and press SPACE, then my text gets updated.
How can I update the text without user having to enter anything?
possibly related - event processing, StringVar is always 1 event behind. Tkinter: set StringVar after <Key> event, including the key pressed