Instantaneous theme changing for PySimpleGUI windows.


Keywords
PySimpleGUI, reskin, realtime, theme, color
License
Other
Install
pip install psg-reskinner==3.1.0

Documentation

Reskinner Plugin for PySimpleGUI

Downloads GitHub issues GitHub forks GitHub stars PyPi Version Python Versions License

pip install PSG-Reskinner

What's Reskinner?

Reskinner is a Python 3 plugin for PySimpleGUI's Tkinter port which enables changing the theme of a PySimpleGUI window on the fly without the need for re-instantiating the window.

Please consider starring the project if you find it useful.

Example Usage (Demo)

# Reskinner Version 3.0.0
from psg_reskinner import animated_reskin, reskin, __version__
from random import choice as rc

from PySimpleGUI import (
    LOOK_AND_FEEL_TABLE,
    Button,
    Push,
    Text,
    Titlebar,
    Window,
    theme,
    theme_list,
)

right_click_menu = [
    "",
    [["Hi", ["Next Level", ["Deeper Level", ["a", "b", "c"]], "Hoho"]], "There"],
]

window_layout = [
    [Titlebar("Reskinner Demo")],
    [Text("Hello!", font=("Helvetica", 20))],
    [Text("You are currently running the Reskinner demo.")],
    [Text("The theme of this window changes every 2 seconds.")],
    [Text("Changing to:")],
    [
        Button(
            "DarkBlue3",
            k="current_theme",
            font=("Helvetica", 16),
            right_click_menu=right_click_menu,
        )
    ],
    [Text(f"Reskinner v{__version__}", font=("Helvetica", 8), pad=(0, 0)), Push()],
]

window = Window(
    "Reskinner Demo",
    window_layout,
    element_justification="center",
    keep_on_top=True,
)

def _reskin_job():
    themes = theme_list()
    themes.remove(theme())
    new = rc(themes)
    window["current_theme"].update(new)
    animated_reskin(
        window=window,
        new_theme=new,
        theme_function=theme,
        lf_table=LOOK_AND_FEEL_TABLE,
    )
    window.TKroot.after(2000, _reskin_job)

started = False

while True:
    e, v = window.read(timeout=2000)

    if e in (None, "Exit"):
        window.Close()
        break

    if not started:
        _reskin_job()
        started = True

How does it work?

Reskinner runs through each element in a window, then by relying on the element.widget interface to access the underlying Tkinter object, it applies style changes to the window.

What's the story behind psg_reskinner?

Like Unda, I created Reskinner to be a part/feature of a desktop application which I'm developing, however, I decided to open-source it, as I imagined other developers would find such functionality useful in their projects as well.

Development began on Monday 15th August 2022.

Why is it called Reskinner?

I didn't want it to go against the built-in conventions of theme and look_and_feel that PySimpleGUI has.

Standards

Reskinner is:

  • built using Python 3.7 (in PyCharm),

  • fully PEP-8 compliant,

  • distributed under the OSI-Approved MIT License.