RobertJN64 / TKinterModernThemes

A collection of modern themes with code that makes it easy to integrate into a tkinter project.
MIT License
91 stars 7 forks source link

Real-time change mode/theme #5

Closed OlegXio closed 4 months ago

OlegXio commented 4 months ago

Hello, I need to change the mode (light/dark) of an application while it is running, how can this be implemented correctly? I tried it:

import tkinter as tk
from tkinter import ttk
import TKinterModernThemes as TKMT

class SetUp(TKMT.ThemedTKinterFrame):
    def __init__(self, theme, mode, usecommandlineargs=True, usethemeconfigfile=True):
        def changethemecolor():
            mode = self.mode
            if mode == 'light':
                mode = 'dark'
            elif mode == 'dark':
                mode = 'light'
            self.master.destroy()
            SetUp(theme, mode)
        button_qwer = tk.Button(self.master, text="Change themecolor", command=changethemecolor, highlightthickness=0, bd=0, anchor='ne')
        button_qwer.grid(row=1, column=3, padx=3, pady=0)
        self.run()

But my application restarts by itself, but one of the buttons is in a separate window for some reason. If I remove the function of closing the old window self.master.destroy(), the mode changes for the old application too, but without calling the new window it doesn't change in any of the windows :(

OlegXio commented 4 months ago

Ok, I solved the problem with the button appearing in a new window: it needed to be given a parent (self.master) as the first argument. However, still with such a crummy theme change an empty window appears: image

RobertJN64 commented 4 months ago

You can swap the theme in real time by using self.root.tk.call("set_theme", "light") or self.root.tk.call("set_theme", "dark") in the application class.

import TKinterModernThemes as TKMT

class App(TKMT.ThemedTKinterFrame):
    def __init__(self, theme, mode, usecommandlineargs=True, usethemeconfigfile=True):
        super().__init__("Theme Demo", theme, mode,
                         usecommandlineargs=usecommandlineargs, useconfigfile=usethemeconfigfile)

        self.frame = self.addLabelFrame("Accent Button Frame")
        self.frame.AccentButton("Accent Button", self.handle_button_click)
        self.run()

    def handle_button_click(self):
        self.root.tk.call("set_theme", "light")

if __name__ == "__main__":
    App("park", "dark")
RobertJN64 commented 4 months ago

I added some example code to show swapping between light and dark themes.

https://github.com/RobertJN64/TKinterModernThemes/blob/master/TKinterModernThemes/examples/theme_swap.py

Please let me know if you need anything else!

OlegXio commented 4 months ago

thank you, that helped for me. However, I had to change the theme button image along with the theme update, which I easily fixed through reinitializing the button and self.run(). Again, thanks