Create custom ttk style same as 'clam' ttk Theme (button widget specific)

前端 未结 1 1835
爱一瞬间的悲伤
爱一瞬间的悲伤 2020-12-11 09:53

I need to create a custom style for button widgets which has the same appearance as buttons using the ttk \'clam\' theme.

I can set the theme like:

s         


        
相关标签:
1条回答
  • 2020-12-11 09:58

    using this code:

    import Tkinter as tk
    import ttk
    
    def get_element_details(style):
        print('element: %s' % style)
        print('option: %s' % str(s.element_options(style)))
        layout = s.layout(style)
        for elem, elem_dict in layout:
            get_sub_element_details(elem, elem_dict)
        print(layout)
    
    def get_sub_element_details(elem, _dict, depth=1):
        print('%selement: %s' % (''.join(['\t' for i in range(depth)]), elem))
        for key in _dict:
            if key != 'children':
                print('%s%s: %s' % (''.join(['\t' for i in range(depth+1)]), key, _dict[key]))
        print('%soption: %s' % (''.join(['\t' for i in range(depth+1)]), s.element_options(elem)))
        if 'children' in _dict:
            for child, child_dict in _dict['children']:
                get_sub_element_details(child, child_dict, depth+1)
    
    root = tk.Tk()
    widget = ttk.Button(root, text='test')
    widget.grid(sticky='nesw')
    
    style = widget.winfo_class()
    
    s = ttk.Style()
    
    print(s.theme_use())
    print('normal theme')
    get_element_details(style)
    
    print('\nclam theme')
    s.theme_use('clam')
    get_element_details(style)
    

    you can egt details about all the layout and config options of the widget. with the native theme on my box (xp) i get this output:

    element: TButton
    option: ()
        element: Button.button
            sticky: nswe
            option: ()
            element: Button.focus
                sticky: nswe
                option: ()
                element: Button.padding
                    sticky: nswe
                    option: ('-padding', '-relief', '-shiftrelief')
                    element: Button.label
                        sticky: nswe
                        option: ('-compound', '-space', '-text', '-font', '-foreground', '-underline', '-width', '-anchor', '-justify', '-wraplength', '-embossed', '-image', '-stipple', '-background')
    

    and with the clam theme i get:

    element: TButton
    option: ()
        element: Button.border
            border: 1
            sticky: nswe
            option: ('-bordercolor', '-lightcolor', '-darkcolor', '-relief', '-borderwidth')
            element: Button.focus
                sticky: nswe
                option: ('-focuscolor', '-focusthickness')
                element: Button.padding
                    sticky: nswe
                    option: ('-padding', '-relief', '-shiftrelief')
                    element: Button.label
                        sticky: nswe
                        option: ('-compound', '-space', '-text', '-font', '-foreground', '-underline', '-width', '-anchor', '-justify', '-wraplength', '-embossed', '-image', '-stipple', '-background')
    

    note that the clam theme has a Button.border element with options, where the native theme has a Button.button element with no options.

    you can save the layout from the clam theme (either at write time, or you can get it during run time by loading clam theme, fetch layout then switch theme back and load the layout back in) and use that to style the button.

    EDIT in theory this should work:

    import Tkinter as tk
    import ttk
    
    root = tk.Tk()
    
    style = 'TButton'
    
    s = ttk.Style()
    
    #s.theme_use('clam')
    
    #get_element_details(style)
    
    clambuttonlayout = [('Button.border', {'border': '1', 'children': [('Button.focus', {'children': [('Button.padding', {'children': [('Button.label', {'sticky': 'nswe'})], 'sticky': 'nswe'})], 'sticky': 'nswe'})], 'sticky': 'nswe'})]
    
    s.layout('clam.TButton', clambuttonlayout)
    
    b1 = ttk.Button(root, text="Button 1", style='clam.TButton')
    b1.grid()
    b2 = ttk.Button(root, text="Button 2", style='TButton')
    b2.grid()
    
    root.mainloop()
    

    however for some reason when I do this the text no longer appears on the first button... if i figure it out i'll edit again.

    0 讨论(0)
提交回复
热议问题