1

I'm writing an app that has several text input fields. The fields turn yellow when their content is modified. Saving a (changed) field resets the color to white.

I do this by binding the <<Modified>> event of the text widget to a .config(bg='yellow') command. (I also immediately reset the object's 'modified' flag, because otherwise the <<Modified>> event will never be issued again, even after saving. I know that this is inefficient, I could move it to the 'Save' routine. But this is not the problem.)

Now, at the start I want to populate these input fields with file content from disk. The content of these files is inserted in the text fields via the .insert(tk.END, _text from file_) method. This triggers the <<Modified>> event, i. e. the fields all become yellow. So after loading I want to reset the color to white once by calling .config(bg='white').

And this does not work. There are no error messages, the color just stays yellow. And I don't understand why, because it works for the 'Save' button.

What am I doing wrong here? I somehow think that I'm missing some fundamental Tkinter concept.

Here is a minimum version of the code:

import tkinter as tk

root = tk.Tk()

# the text widget
mytext = tk.Text(root)
mytext.pack()

# add yellowing when content is modified
mytext.bind('<<Modified>>', lambda e: e.widget.configure(background='yellow'))
# and immediate reset the internal modified flag
mytext.bind('<<Modified>>', lambda e: e.widget.edit_modified(0), add='+')

# this is the SAVE button without the actual saving
# so it should just reset the color to white and THIS WORKS
mybutton=tk.Button(root,text="Save (Reset Color)",command= lambda : mytext.configure(background='white'))
mybutton.pack()

# this is the initial filling of the text widget with some text
mytext.insert(tk.END, 'sample text from file') # this makes the widget yellow upon program start
mytext.config(bg='white') # <=== THIS DOES _NOT_ MAKE THE WIDGET WHITE AGAIN

root.mainloop()
  • I recommend you bind the event to a proper function, which will make it easier to debug. Then, add a print statement in that function and another one where you change the color to learn the order in which those lines of code execute. – Bryan Oakley Aug 30 '22 at 16:57

1 Answers1

0

I believe I have understood your question. I think the easiest way to do this is with the after method. Then you could let it show yellow for 1 second (or how ever long) and then change to white. Is this what you are looking for?

import tkinter as tk


def change_white():
    mytext.config(bg="white")

    
root = tk.Tk()

# the text widget
mytext = tk.Text(root)
mytext.pack()

# add yellowing when content is modified
mytext.bind('<<Modified>>', lambda e: e.widget.configure(background='yellow'))
# and immediate reset the internal modified flag
mytext.bind('<<Modified>>', lambda e: e.widget.edit_modified(0), add='+')

# this is the SAVE button without the actual saving
# so it should just reset the color to white and THIS WORKS
mybutton=tk.Button(root,text="Save (Reset Color)",command= lambda : mytext.configure(background='white'))
mybutton.pack()

# this is the initial filling of the text widget with some text
mytext.insert(tk.END, 'sample text from file') # this makes the widget yellow upon program start

root.after(1000, change_white)

root.mainloop()
Rory
  • 661
  • 1
  • 6
  • 15