Reputation: 1888
I'm trying to do something simple -- change the fill color of a ttk Entry widget in a Python script to show an invalid entry. My question is not specifically how to do this (though I'd like to know!) but rather how to figure out how to do this given generally available documentation and resources.
I've read everything I can find about ttk and styles (including several StackOverflow questions), and while the process of applying styles looks straightforward if you know all the keywords/options you need, I can't figure out how to approach the problem if the keywords/options are unknown.
For an accepted answer to this question, I'd like to see the process of figuring out how to set the background color of a ttk Entry widget, that leads to a solution that works with Python. I want to learn to fish.
Upvotes: 1
Views: 1042
Reputation: 8037
First of all, SO isnt designed to substitude regular documentation or tutorials. But I agree with the OP that ttk lack a little bit of a overall description.
import tkinter as tk
import tkinter.ttk as ttk
from ttkthemes import ThemedStyle
ttk isnt imported by tkinter itself and needs to be explicitly imported. It is recommended to import it as ttk to avoid name conflicts.
style = ttk.Style(root)
style.theme_use('default')
The style class is designed to manipulate the styling database. Themes are always used, even if you didnt defined one. A list of themes can be found here or here. Or you can define your own with theme_create, like here
button = ttk.Button(root, text='abc')
button.pack(expand=True, fill='both')
style_name = button.winfo_class()
Every ttk.widget
has the styling option and can be adressed by .winfo_class
style.layout(style_name,
[('Button.border', {'sticky': 'nswe', 'border': '1', 'children': [
('Button.focus', {'sticky': 'nswe', 'children': [
('Button.padding', {'sticky': 'nswe', 'children': [
('Button.label', {'sticky': 'nswe'})
]})
]})
]}
)])
Manipulating the layout gives you trivial options like to have a button on the right or left side. But in addition with element_create it can be a powerfull tool. Like Scrollbar.thumb, Scrollbar.trough, Downarrow.
print(style.layout(style_name))
print('Layout')
Get the current layout and try this with different themes and may mix them together with element_create or try to use the vsapi under windows/visual_styles_api.
print(style.element_options('Button.label'))
print('label')
print(style.map(style_name))
print('map')
To simply configure some colors I have found, and linked in my answer, a list of colors that can be configured but dosent mean they necessary have an effect.
Options that are available don't necessarily have an effect, and it's not an error to modify a bogus option.
For your entry background configure ttk::style configure TEntry -fieldbackground color
that can also be found in the list of colors.
widget = ttk.Entry(root, text='abc', style='My.TEntry')
style.configure("My.TEntry",
foreground="grey",
fieldbackground="black")
Example:
import tkinter as tk
import tkinter.ttk as ttk
from ttkthemes import ThemedStyle
bg_color = '#091424'
fg_color = '#ffcfcf'
arrow_bg = '#8c101e'
border_color = '#db994c'
highlight_color = '#372940'
pressed_color = arrow_bg
root = tk.Tk()
style = ttk.Style(root)
style.theme_use('clam')#background/arrowcolor
frame =tk.Frame(root)
frame.pack()
widget = ttk.Spinbox(frame, text='abc', style="my.TSpinbox")
widget.pack(expand=True, fill='both')
style_name = widget.winfo_class()
style.layout('my.TSpinbox',
[('Spinbox.field', {'sticky': 'nswe', 'children': [
('Spinbox.background', {'sticky': 'nswe', 'children': [
('Spinbox.padding', {'sticky': 'nswe', 'children': [
('Spinbox.innerbg', {'sticky': 'nswe', 'children': [
('Spinbox.textarea', {'expand': '1', 'sticky': 'nswe'})
]})
]}),
('Spinbox.uparrow', {'side': 'top', 'sticky': 'nse'}),
('Spinbox.downarrow', {'side': 'bottom', 'sticky': 'nse'})
]})
]})
])
style.configure('my.TSpinbox',
background=bg_color,
foreground=fg_color,
arrowcolor=arrow_bg,
arrowsize=20,
relief="raised",
bordercolor=border_color,
lightcolor='red',
darkcolor='green',
troughcolor='pink',
)
style.map("my.TSpinbox",
arrowcolor = [('pressed', pressed_color),
('active', highlight_color),
('disabled', '#ffffff')])
print(style.layout(style_name))
print('Layout')
print(style.element_options('Spinbox.field'))
print('field')
print(style.element_options('Spinbox.downarrow'))
print('downarrow')
print(style.element_options('Spinbox.uparrow'))
print('uparrow')
print(style.element_options('Spinbox.padding'))
print('padding')
print(style.element_options('Spinbox.background'))
print('background')
print(style.element_options('Spinbox.textare'))
print('textarea')
print(style.element_options('Spinbox.innerbg'))
print('innerbg')
print(style.map(style_name))
print('map')
Additional References:
Upvotes: 2