I'm trying to figure out how to style ttk buttons from Python (ttk.Button) on Linux, and right now I'm focusing on the border. All of the built-in themes (alt, clam, classic, and default) appear to use the Button.border element, but they list differing options and don't necessarily appear to support some listed options.
alt lists -background, -bordercolor, -default, -borderwidth, and -relief. However, -bordercolor is ignored.
clam lists -bordercolor, -lightcolor, -darkcolor, -relief, and -borderwidth. However, -borderwidth is ignored.
classic lists -background, -borderwidth, -relief, and -default.
default lists -background, -borderwidth, and -relief.
Why is it that for the Button.border element only clam supports -bordercolor, -lightcolor, and -darkcolor, and only the others support -borderwidth? Shouldn't all of the themes support all of those options?
I'm by no means proficient in reading Tcl, but I don't see anything in the ttk theme files (altTheme.tcl, clamTheme.tcl, classicTheme.tcl, defaults.tcl) that indicate the Button.border element is customized or any reference to it at all. There's only some configure and map calls for the TButton style.
This is the code I used to view the results above:
import pprint
import tkinter as tk
import tkinter.ttk as ttk
def theme_changed(theme):
style.theme_use(theme)
print(theme)
pprint.pprint(style.layout('TButton'))
pprint.pprint(style.element_options('Button.border'))
style.configure(
'Custom.TButton',
background='#FFFFFF', # White
bordercolor='#00FF00', # Green
lightcolor='#FF0000', # Red
darkcolor='#0000FF', # Blue
borderwidth=4,
foreground='#00FFFF', # Cyan
)
root = tk.Tk()
style = ttk.Style()
combo = ttk.Combobox(root, values=sorted(style.theme_names()), state='readonly')
combo.set(style.theme_use())
combo.bind('<<ComboboxSelected>>', lambda _e: theme_changed(combo.get()))
combo.pack()
theme_changed(style.theme_use())
button = ttk.Button(root, text="Normal Button")
button.pack()
button = ttk.Button(root, style="Custom.TButton", text="Custom Button")
button.pack()
root.mainloop()