TomSchimansky / CustomTkinter

A modern and customizable python UI-library based on Tkinter
MIT License
11.58k stars 1.08k forks source link

[Question] Change default color theme without restart #898

Open infinitel8p opened 1 year ago

infinitel8p commented 1 year ago

Can I somwhow use customtkinter.set_default_color_theme without restarting my application? (For example changing appearance mode without restart works perfect, changing theme requires me to restart my application)

JardarIversen commented 1 year ago

In my app I made a function to reload the page, that is called after changing the color theme. First keep track of what what widgets are in your window, delete them then recreate them with the same function that put them there

infinitel8p commented 1 year ago

In my app I made a function to reload the page, that is called after changing the color theme. First keep track of what what widgets are in your window, delete them then recreate them with the same function that put them there

Do you have some (sample-) code of how you did it? Would be much appreciated

JardarIversen commented 1 year ago

Ok i made this example for you. I make the UI as a class, so it is easy to reinitialize after I delete the ui.

from customtkinter import *

class SomeUI(CTkFrame):
    def __init__(self, master, change_color_theme):
        super().__init__(master=master)

        self.some_label = CTkLabel(self, text="Hello World")
        self.some_label.pack(pady=20)

        self.select_color_theme_optionmenu = CTkOptionMenu(self,
                                                           values=["Green", "Blue", "Dark-blue"],
                                                           command=change_color_theme)
        self.select_color_theme_optionmenu.pack()

class App(CTk):
    def __init__(self):
        super().__init__()

        self.geometry("400x400")
        self.current_ui = []

        self.main_content = SomeUI(self, self.change_color_theme)
        self.main_content.pack(expand=True, fill=BOTH)
        self.current_ui.append(self.main_content)

    def change_color_theme(self, color):
        set_default_color_theme(color.lower())
        self.reset_current_ui()

    def reset_current_ui(self):
        for widget in self.current_ui:
            widget.destroy()
        self.main_content = SomeUI(self, self.change_color_theme)
        self.main_content.pack(expand=True, fill=BOTH)
        self.current_ui.append(self.main_content)

if __name__ == '__main__':
    app = App()
    app.mainloop()

In my own app I have multiple pages, so i keep track of which one i am on so if I need to reset the page I just run the function to initialize the one I was on after deleting its widgets. Also note you only need to delete the main frame which everything else is in, not all induvidual widgets

avalon60 commented 1 year ago

Interesting, but doesn't this destroys the state of the application? That is to say, if you have been entering data, you lose it.

Also there is a fg_color setting for CTk, which you could obtain, using ThemeManager.theme dictionary lookup, and then set explicitly.