how to know all style options of a ttk widget

前端 未结 3 1211
孤城傲影
孤城傲影 2020-12-30 03:45

This problem nearly makes me craze. I am a new beginner and without knowledge of tck/tk. I have done carefully search on the internet but haven\'t found a good solution.

相关标签:
3条回答
  • 2020-12-30 04:21

    Building on SunBear's script:

    import tkinter as tk
    import tkinter.ttk as ttk
    
    def 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 elements
    
    def 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.

    0 讨论(0)
  • 2020-12-30 04:32

    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

    0 讨论(0)
  • 2020-12-30 04:47

    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 tk
    import tkinter.ttk as ttk
    
    def 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')
    
    0 讨论(0)
提交回复
热议问题