In the following code, the show_widget_validity()
function either applies a custom style that has just a change to the background color of a widget's existing style, or restores the original style. This is a library routine, so does not take complete control of the style. The background color appears to be reconfigured correctly, as shown by the background style description reported in the entry widget after each change. However, the actual background color of the widget does not change.
This behavior is seen on Linux with Python 2.7 and 3.6, and on Windows with Python 2.7; I haven't tested other environments.
Any clues as to the cause of this behavior, or code changes necessary to account for it, would be appreciated.
EDIT: Using "fieldbackground" instead of "background" is effective on Linux but not Windows, and does not allow revision of the background color in the disabled state.
try:
import Tkinter as tk
except:
import tkinter as tk
try:
import ttk
except:
from tkinter import ttk
def show_widget_validity(widget, is_valid):
invalid_color = "#fff5ff"
invalid_disabled_color = "#f6f0f6"
sname = widget["style"] or widget.winfo_class()
if sname.startswith("Invalid."):
if is_valid:
widget['style'] = sname[8:]
else:
if not is_valid:
invname = "Invalid." + sname
ttk.Style().configure(invname, background=[('disabled', invalid_disabled_color), ('active', invalid_color)])
# Simpler, but also ineffective:
#ttk.Style().configure(invname, background=invalid_color)
widget['style'] = invname
def show_invalid():
show_widget_validity(entry, False)
entry_var.set(ttk.Style().lookup(entry["style"] or entry.winfo_class(), "background"))
def show_valid():
show_widget_validity(entry, True)
entry_var.set(ttk.Style().lookup(entry["style"] or entry.winfo_class(), "background"))
root = tk.Tk()
root.title("Testing of Style Customization")
appframe = tk.Frame(root, padx=12, pady=12)
appframe.pack(expand=True, fill=tk.BOTH)
entry_var = tk.StringVar()
entry = ttk.Entry(appframe, textvariable=entry_var, width=40, exportselection=False)
entry.grid(row=0, column=0, padx=3, pady=3, sticky=tk.EW)
btnframe = ttk.Frame(appframe)
btnframe.grid(row=1, column=0)
invalid_btn = ttk.Button(btnframe, text="Make invalid", command=show_invalid)
valid_btn = ttk.Button(btnframe, text="Make valid", command=show_valid)
invalid_btn.grid(row=0, column=0, padx=3, pady=3)
valid_btn.grid(row=0, column=1, padx=3, pady=3)
root.mainloop()