Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Instantaneous theme changing for PySimpleGUI and FreeSimpleGUI windows.

License

definite-d/reskinner

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Reskinner: Dynamic Theme Switching for PySimpleGUI and FreeSimpleGUI

PyPI Version Python Versions License uv Ruff Downloads GitHub issues GitHub forks GitHub stars

Reskinner Demo

V4 Release

With the release of Version 4.0.0, the project is now officially known as "Reskinner". This is a re-write, focusing on improvements to the structure and API of the project.

Biggest changes

  • Full support for FreeSimpleGUI is here. Thanks to @deajan for the contribution and bringing it to my notice.
  • The entire project has been rewritten from scratch for better maintainability, extensibility, and performance.
  • The animated_reskin function is no more... because the reskin function itself has animation parameters baked in now.
  • The API for reskin has been improved to require only 2 parameters; the window, and the desired theme.
  • The project's minimum supported Python version is now 3.8. Python 3.7 support is back from 4.0.1
  • Mentions of HSV interpolation in the code have been corrected; it's HSL.

Reskinner is a powerful library for PySimpleGUI and FreeSimpleGUI, enabling dynamic theme switching at runtime without window recreation. It provides a seamless way to update your application's look and feel on the fly.

Features

  • Dynamic theme switching without window recreation
  • Supports both PySimpleGUI and FreeSimpleGUI
  • Easy integration with existing applications
  • Precise control over theme transitions with animations and 3 supported interpolation modes.
  • Lightweight and dependency-minimal

Installation

Using pip (PyPI)

# For PySimpleGUI
pip install "reskinner[psg]"

# For FreeSimpleGUI
pip install "reskinner[fsg]"

Using uv

# Install uv if not already installed
pip install uv

# For PySimpleGUI
uv add reskinner[psg]

# For FreeSimpleGUI
uv add reskinner[fsg]

Quick Start

from random import choice
import PySimpleGUI as sg  # or import FreeSimpleGUI as sg
from reskinner import reskin

# Create a simple window
layout = [
    [sg.Text("Hello, Reskinner!")],
    [sg.Button("Change Theme"), sg.Button("Exit")]
]

window = sg.Window("Reskinner Demo", layout)

themes = sg.theme_list()
current_theme = sg.theme()

def change_theme():
    new_theme = choice([t for t in themes if t != current_theme])
    reskin(window, new_theme)
    return new_theme

while True:
    event, values = window.read()

    if event in (sg.WIN_CLOSED, 'Exit'):
        break

    if event == "Change Theme":
        current_theme = change_theme()

window.close()

Documentation

Core Function

reskin

from reskinner import reskin
import PySimpleGUI as sg

# Apply a new theme instantly
reskin(window=my_window, new_theme="DarkBlue3", theme_function=sg.theme)

Advanced Usage

Custom Interpolation

Reskinner supports three different interpolation modes for theme transitions; hsl, hue, and rgb (default):

from reskinner import reskin
import PySimpleGUI as sg

# Smooth, animated color transition using HSL interpolation
reskin(
    window=window,
    new_theme="DarkAmber",
    theme_function=sg.theme,
    duration_in_milliseconds=800,
    interpolation_mode="hsl",
)

Element-Specific Filtering

Customize whether specific elements are styled during reskinning:

from reskinner import reskin
import PySimpleGUI as sg

# Skip elements you don't want to restyle
reskin(
    window=window,
    new_theme="LightGreen",
    theme_function=sg.theme,
    element_filter=lambda e: e.key != "skip_me"
)

Using a named easing function

This uses one of Reskinner’s built-in easing functions (based on https://easing.net) for a smooth, natural animation.

from reskinner import reskin
import PySimpleGUI as sg

# Apply a theme with animation and built-in easing
reskin(
    window=window,
    new_theme="DarkBlue",
    duration=1000,  # milliseconds
    interpolation_mode="rgb",
    easing_function="ease_in_out_sine",
)

Using a custom easing function

Any callable accepting a float between 0 and 1, and returning a float in the same range, is valid as a custom easing function. In this example, we use the golden ratio as our easing function

from math import pow
from reskinner import reskin
import PySimpleGUI as sg


def golden_ease_out(t: float) -> float:
    phi = (1 + 5 ** 0.5) / 2  # ≈ 1.618
    return 1 - pow(1 - t, phi)

# Apply a theme with golden-ratio-based easing
reskin(
    window=window,
    new_theme="DarkGreen5",
    duration=1000,
    interpolation_mode="rgb",
    easing_function=golden_ease_out,
)

Compatibility

  • Python 3.8+
  • PySimpleGUI 4.60.0+ or FreeSimpleGUI 5.0.0+ (Tkinter variant only; Reskinner doesn't support *Qt, *Wx, or *Web variants)
  • Tkinter (included with Python)

License

This project is licensed under the MIT License - see the LICENSE file for details.

Acknowledgments

FAQs

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.

About

Instantaneous theme changing for PySimpleGUI and FreeSimpleGUI windows.

Topics

Resources

License

Stars

Watchers

Forks

Languages