how to know all style options of a ttk widget
I found your question interesting as I had asked myself the same question but have not found time to address it until now. I have written a function called stylename_elements_options(stylename)
to do just this. Sharing it here. Hope it can benefit you (although it is 6 months late) and any tkinter users asking the same question.
Script:
import tkinter as tkimport tkinter.ttk as ttkdef stylename_elements_options(stylename): '''Function to expose the options of every element associated to a widget stylename.''' try: # Get widget elements style = ttk.Style() layout = str(style.layout(stylename)) print('Stylename = {}'.format(stylename)) print('Layout = {}'.format(layout)) elements=[] for n, x in enumerate(layout): if x=='(': element="" for y in layout[n+2:]: if y != ',': element=element+str(y) else: elements.append(element[:-1]) break print('\nElement(s) = {}\n'.format(elements)) # Get options of widget elements for element in elements: print('{0:30} options: {1}'.format( element, style.element_options(element))) except tk.TclError: print('_tkinter.TclError: "{0}" in function' 'widget_elements_options({0}) is not a regonised stylename.' .format(stylename))stylename_elements_options('my.Vertical.TScrollbar')
The issue is that if you really want to control a style in detail you need to use the layout. So first identify the widget class using:
>>b=ttk.Button(None)>>b.winfo_class()'TButton
Then use the command
>>> s.layout('TButton')[("Button.border", {"children": [("Button.focus", {"children": [("Button.spacing",{"children": [("Button.label", {"sticky": "nswe"})], "sticky": "nswe"})], "sticky": "nswe"})], "sticky": "nswe", "border": "1"})]
Finally change what you want:
s.layout("MYButton.TButton",[("Button.border", {"children": [("Button.focus", {"children": [("Button.spacing", {"children": [("Button.label", {"sticky": "nswe"})], "sticky": "nswe"})], "sticky": "nswe"})], "sticky": "we", "border": "1"})]
This made the trick for me and finally provides me a way to control my ttk widget!!!
Luca
Building on SunBear's script:
import tkinter as tkimport tkinter.ttk as ttkdef iter_layout(layout, tab_amnt=0, elements=[]): """Recursively prints the layout children.""" el_tabs = ' '*tab_amnt val_tabs = ' '*(tab_amnt + 1) for element, child in layout: elements.append(element) print(el_tabs+ '\'{}\': {}'.format(element, '{')) for key, value in child.items(): if type(value) == str: print(val_tabs + '\'{}\' : \'{}\','.format(key, value)) else: print(val_tabs + '\'{}\' : [('.format(key)) iter_layout(value, tab_amnt=tab_amnt+3) print(val_tabs + ')]') print(el_tabs + '{}{}'.format('} // ', element)) return elementsdef stylename_elements_options(stylename, widget): """Function to expose the options of every element associated to a widget stylename.""" try: # Get widget elements style = ttk.Style() layout = style.layout(stylename) config = widget.configure() print('{:*^50}\n'.format(f'Style = {stylename}')) print('{:*^50}'.format('Config')) for key, value in config.items(): print('{:<15}{:^10}{}'.format(key, '=>', value)) print('\n{:*^50}'.format('Layout')) elements = iter_layout(layout) # Get options of widget elements print('\n{:*^50}'.format('element options')) for element in elements: print('{0:30} options: {1}'.format( element, style.element_options(element))) except tk.TclError: print('_tkinter.TclError: "{0}" in function' 'widget_elements_options({0}) is not a regonised stylename.' .format(stylename))widget = ttk.Button(None)class_ = widget.winfo_class()stylename_elements_options(class_, widget)
Prints the config options as well as the layout tree.