Skip to content

styles

tkinter styles

Uses ttk Themed Styles

Docs: https://tkdocs.com/tutorial/styles.html List of Themes: https://wiki.tcl-lang.org/page/List+of+ttk+Themes awlight/awdark theme download: https://wiki.tcl-lang.org/page/awthemes Fonts: https://tkdocs.com/tutorial/fonts.html

create_hover(parent)

Create tkinter frame hovering above the current widget

E.G. window_frame, close = create_hover(widget) ttk.Button(window_frame, text='Close', command=close).pack()

Parameters:

Name Type Description Default
parent Misc | RootWithStyle

tk widget or root

required

Returns:

Type Description

function close() -> None (releases widget and destroys hover window)

Source code in mmg_toolbox/tkguis/misc/styles.py
def create_hover(parent: tk.Misc | RootWithStyle):
    """
    Create tkinter frame hovering above the current widget

    E.G.
    window_frame, close = create_hover(widget)
    ttk.Button(window_frame, text='Close', command=close).pack()

    :param parent: tk widget or root
    :returns: ttk.Frame object inside tk.TopLevel with no window management
    :returns: function close() -> None (releases widget and destroys hover window)
    """
    root = create_root('', parent)
    root.wm_overrideredirect(True)

    window = ttk.Frame(root, borderwidth=20, relief=tk.RAISED)
    window.pack(side=tk.TOP, fill=tk.BOTH)

    def destroy(event=None):
        root.grab_release()
        root.destroy()

    root.grab_set()
    return window, destroy

create_root(window_title, parent=None)

Create tkinter root object with style attribute

Source code in mmg_toolbox/tkguis/misc/styles.py
def create_root(window_title: str, parent: tk.Misc | RootWithStyle | None = None) -> RootWithStyle:
    """Create tkinter root object with style attribute"""
    if parent:
        root = tk.Toplevel(parent)
        # root.geometry(f"+{parent.winfo_x()+100}+{parent.winfo_y()+100}")
        root.transient(parent)
        if hasattr(parent, 'style'):
            root.style = parent.style
    else:
        root = tk.Tk()

    def update(event):
        root.update()
        print(root.winfo_reqwidth(), root.winfo_screenheight())
        print(root.winfo_screenwidth(), root.winfo_screenheight())

    # root.bind('<Configure>', update)

    if not hasattr(root, 'style'):
        style = create_style(root)
        root.style = style

    # Fix background (on windows)
    root.configure(bg=root.style.lookup('.', 'background'))

    root.wm_title(window_title)
    # self.root.minsize(width=640, height=480)
    # root.maxsize(width=root.winfo_screenwidth() * 3 // 4, height=root.winfo_screenheight() * 3 // 4)
    root.maxsize(width=int(root.winfo_screenwidth() - 50), height=int(root.winfo_screenheight()) - 100)
    return root

extra_styles(style)

Add additional styles to use on individual ttk components

Source code in mmg_toolbox/tkguis/misc/styles.py
def extra_styles(style: ttk.Style):
    """
    Add additional styles to use on individual ttk components
    """
    # style.configure("Red.TLabel", foreground='red', font='TkDefaultFont 24 bold')
    style.configure("title.TLabel", foreground='red', font='times 24 bold')
    style.configure("error.TLabel", foreground='red')
    style.configure("smallMsg.TLabel", font='TkDefaultFont 10 bold')

stylename_elements_options(widget)

Function to expose the options of every element associated to a widget stylename.

widget = ttk.Button(None)
class_ = widget.winfo_class()
stylename_elements_options(class_, widget)
Source code in mmg_toolbox/tkguis/misc/styles.py
def stylename_elements_options(widget: tk.Misc):
    """
    Function to expose the options of every element associated to a widget stylename.

        widget = ttk.Button(None)
        class_ = widget.winfo_class()
        stylename_elements_options(class_, widget)
    """

    try:
        # Get widget elements
        stylename = widget.winfo_class()
        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))

theme_menu(style)

Generate theme menu dict

Source code in mmg_toolbox/tkguis/misc/styles.py
def theme_menu(style: ttk.Style) -> dict:
    """Generate theme menu dict"""
    menu = {
        "Themes": {
            name: lambda n=name: use_theme(style, n)
            for name in style.theme_names()
        }
    }
    return menu

update_text_style(widget, style)

Update a tk.Text widget with the current style

Source code in mmg_toolbox/tkguis/misc/styles.py
def update_text_style(widget: tk.Text, style: ttk.Style):
    """
    Update a tk.Text widget with the current style
    """
    widget.configure(
        bg=style.lookup('.', 'background'),
        fg=style.lookup('.', 'foreground'),
        font=style.lookup('.', 'font') or 'TkDefaultFont',
    )