TomSchimansky / CustomTkinter

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

CTkEntry background color when disabled is different than for CTkTextbox #2599

Closed Ju-plop closed 1 month ago

Ju-plop commented 1 month ago

Hello,

When disabled, the CTkTextbox widget has a grey background color. This is not the case for the CTkEntry widget which has a white color with a light grey border whether is is active or disabled.

Could the look of the disabled CTkTextbox widget be applied to the disabled CTkEntry widget?

I saw that similar issues have already been brought up to choose the background color of the CTkEntry widget when it is disabled ( #1870, #922) but it does not answer my question.

Thank you!

dipeshSam commented 1 month ago

What about setting it manually?

Ju-plop commented 1 month ago

I could do that but I do not know how:

Thank you

dipeshSam commented 1 month ago

Please clarify it what do you want to modify CTkTextbox or CTkEntry? Or both?

Ju-plop commented 1 month ago

I want to modify CTkEntry to give it the same disabled look as CTkTextbox.

dipeshSam commented 1 month ago

As you asked about how to retrieve existing widget color information, you can use ThemeManager to get color and all other data value of any widget in customtkinter.

Sample code:

from customtkinter import ThemeManager

text_box_data = ThemeManager.theme["CTkTextbox"]

print(text_box_data)

Output:

{'corner_radius': 6, 'border_width': 0, 'fg_color': ['#F9F9FA', '#1D1E1E'], 'border_color': ['#979DA2', '#565B5E'], 'text_color': ['gray10', '#DCE4EE'], 'scrollbar_button_color': ['gray55', 'gray41'], 'scrollbar_button_hover_color': ['gray40', 'gray53']}

Now, to change widget properties on State change, you can override .configure() method in CTkEntry or in any widget. Here is sample code for CTkEntry to change its all the properties on state change:

from customtkinter import CTk, CTkEntry
from customtkinter import set_appearance_mode

class Entry(CTkEntry):
    def __init__(self, *args, **kwargs):
        """All `CTkEntry` arguments are supported."""
        super().__init__(*args, **kwargs)

        self._normal_properties = {}
        self._disabled_properties = {}

    def set_disabled_properties(self, **kwargs):
        self._disabled_properties.update(kwargs)
        self._normal_properties.update({key: self.cget(key) for key in self._disabled_properties.keys()})

    def configure(self, require_redraw=False, **kwargs):
        if "state" in kwargs:
            if kwargs["state"] == "disabled":
                super().configure(**self._disabled_properties)
            else:
                super().configure(**self._normal_properties)

        return super().configure(require_redraw, **kwargs)

if __name__ == "__main__":
    app = CTk()
    set_appearance_mode("Dark")
    app.configure(width=500, height=300)

    entry = Entry(app, placeholder_text="Type something...")
    entry.place(relx=0.5, anchor="center", rely=0.5)

    entry.set_disabled_properties(border_width=0, placeholder_text_color="#6b6b60", text_color="#9ea3aa")

    entry.configure(state="disabled")
    # entry.configure(state="normal")

    app.mainloop()

Outputs: With disabled With_Disabled With normal again Normal_again

The two methods set_disabled_properties() and configure() in above class code are completely widget-independent, you can use them to override any widget like CTkTextbox or CTkLabel etc.

Hope it would be helpful for you. Let me know what you expect more from above explanation. Regards.

Ju-plop commented 1 month ago

This works perfectly, thank you!