From 8a87b6f926105afb072ab77ffcec359b025296ff Mon Sep 17 00:00:00 2001 From: Tom Schimansky Date: Fri, 27 May 2022 00:12:37 +0200 Subject: [PATCH] updated color for blue theme --- customtkinter/assets/themes/blue.json | 45 +++++++------ customtkinter/widgets/ctk_optionmenu.py | 66 ++++++++++++++----- examples/simple_example.py | 5 +- setup.cfg | 2 +- .../test_tk_variables.py | 10 ++- 5 files changed, 88 insertions(+), 40 deletions(-) diff --git a/customtkinter/assets/themes/blue.json b/customtkinter/assets/themes/blue.json index 84977f9..b4d1106 100644 --- a/customtkinter/assets/themes/blue.json +++ b/customtkinter/assets/themes/blue.json @@ -1,34 +1,37 @@ { "color": { - "window_bg_color": ["gray95", "gray12"], - "button":["#5B97D3", "#3373B8"], - "button_hover": ["#4A7BAD", "#1D538D"], - "button_border": ["gray40", "#D5D9DE"], - "checkbox_border": ["gray40", "#D5D9DE"], + "window_bg_color": ["#EBEBEC", "#212325"], + "button": ["#3B8ED0", "#1F6AA5"], + "button_hover": ["#36719F", "#144870"], + "button_border": ["#3E454A", "#949A9F"], + "checkbox_border": ["#3E454A", "#949A9F"], "checkmark": ["white", "gray90"], - "entry": ["white", "gray24"], - "entry_border": ["gray70", "gray32"], + "entry": ["#F9F9FA", "#343638"], + "entry_border": ["#979DA2", "#565B5E"], "entry_placeholder_text": ["gray52", "gray62"], - "frame_border": ["#A7C2E0", "#5FB4DD"], - "frame_low": ["#E3E4E5", "gray16"], - "frame_high": ["#D7D8D9", "gray22"], + "frame_border": ["#979DA2", "#1F2122"], + "frame_low": ["#D1D5D8", "#2A2D2E"], + "frame_high": ["#D7D8D9", "#343638"], "label": [null, null], - "text": ["gray20", "#D5D9DE"], + "text": ["gray10", "#DCE4EE"], "text_disabled": ["gray60", "#777B80"], "text_button_disabled": ["gray40", "gray74"], - "progressbar": ["#6B6B6B", "gray0"], - "progressbar_progress": ["#5B97D3", "#3373B8"], + "progressbar": ["#939BA2", "#4A4D50"], + "progressbar_progress": ["#3B8ED0", "#1F6AA5"], "progressbar_border": ["gray", "gray"], - "slider": ["#6B6B6B", "gray0"], - "slider_progress": ["white", "gray40"], - "slider_button": ["#5B97D3", "#3373B8"], - "slider_button_hover": ["#4A7BAD", "#1D538D"], - "switch": ["gray70", "gray35"], - "switch_progress": ["#5B97D3", "#3373B8"], + "slider": ["#939BA2", "#4A4D50"], + "slider_progress": ["white", "#AAB0B5"], + "slider_button": ["#3B8ED0", "#1F6AA5"], + "slider_button_hover": ["#36719F", "#144870"], + "switch": ["#939BA2", "#4A4D50"], + "switch_progress": ["#3B8ED0", "#1F6AA5"], "switch_button": ["gray36", "#D5D9DE"], "switch_button_hover": ["gray20", "gray100"], - "optionmenu_button": ["#4A7BAD", "#1D538D"], - "optionmenu_button_hover": ["#D7D8D9", "gray22"] + "optionmenu_button": ["#36719F", "#144870"], + "optionmenu_button_hover": ["#27577D", "#203A4F"], + "dropdown_color": ["#A8ACB1", "#535353"], + "dropdown_hover": ["#D6DCE2", "#46484A"], + "dropdown_text": ["gray10", "#DCE4EE"] }, "text": { "macOS": { diff --git a/customtkinter/widgets/ctk_optionmenu.py b/customtkinter/widgets/ctk_optionmenu.py index a05291e..922f27d 100644 --- a/customtkinter/widgets/ctk_optionmenu.py +++ b/customtkinter/widgets/ctk_optionmenu.py @@ -17,6 +17,9 @@ class CTkOptionMenu(CTkBaseClass): fg_color="default_theme", button_color="default_theme", button_hover_color="default_theme", + dropdown_color="default_theme", + dropdown_hover_color="default_theme", + dropdown_text_color="default_theme", variable=None, values=None, command=None, @@ -37,6 +40,9 @@ class CTkOptionMenu(CTkBaseClass): self.fg_color = ThemeManager.theme["color"]["button"] if fg_color == "default_theme" else fg_color self.button_color = ThemeManager.theme["color"]["optionmenu_button"] if button_color == "default_theme" else button_color self.button_hover_color = ThemeManager.theme["color"]["optionmenu_button_hover"] if button_hover_color == "default_theme" else button_hover_color + self.dropdown_color = ThemeManager.theme["color"]["dropdown_color"] if dropdown_color == "default_theme" else dropdown_color + self.dropdown_hover_color = ThemeManager.theme["color"]["dropdown_hover"] if dropdown_hover_color == "default_theme" else dropdown_hover_color + self.dropdown_text_color = ThemeManager.theme["color"]["dropdown_text"] if dropdown_text_color == "default_theme" else dropdown_text_color # shape self.corner_radius = ThemeManager.theme["shape"]["button_corner_radius"] if corner_radius == "default_theme" else corner_radius @@ -50,6 +56,8 @@ class CTkOptionMenu(CTkBaseClass): # callback and hover functionality self.function = command self.variable = variable + self.variable_callback_blocked = False + self.variable_callback_name = None self.state = state self.hover = hover self.click_animation_running = False @@ -82,6 +90,10 @@ class CTkOptionMenu(CTkBaseClass): self.set_cursor() self.draw() # initial draw + if self.variable is not None: + self.variable_callback_name = self.variable.trace_add("write", self.variable_callback) + self.set(self.variable.get(), from_variable_callback=True) + def set_scaling(self, *args, **kwargs): super().set_scaling(*args, **kwargs) @@ -148,18 +160,11 @@ class CTkOptionMenu(CTkBaseClass): y_position=self.winfo_rooty() + self.current_height + 4, width=self.current_width, values=self.values, - command=self.set) - - def set(self, value: str): - self.current_value = value - - if self.text_label is not None: - self.text_label.configure(text=self.current_value) - else: - self.draw() - - def get(self) -> str: - return self.current_value + command=self.set, + fg_color=self.dropdown_color, + button_hover_color=self.dropdown_hover_color, + button_color=self.dropdown_color, + text_color=self.dropdown_text_color) def configure(self, *args, **kwargs): require_redraw = False # some attribute changes require a call of self.draw() at the end @@ -203,9 +208,17 @@ class CTkOptionMenu(CTkBaseClass): del kwargs["command"] if "variable" in kwargs: + if self.variable is not None: # remove old callback + self.variable.trace_remove("write", self.variable_callback_name) + self.variable = kwargs["variable"] - if self.text_label is not None: - self.text_label.configure(textvariable=self.variable) + + if self.variable is not None and self.variable != "": + self.variable_callback_name = self.variable.trace_add("write", self.variable_callback) + self.set(self.variable.get(), from_variable_callback=True) + else: + self.variable = None + del kwargs["variable"] if "width" in kwargs: @@ -255,6 +268,26 @@ class CTkOptionMenu(CTkBaseClass): if self.click_animation_running: self.on_enter() + def variable_callback(self, var_name, index, mode): + if not self.variable_callback_blocked: + self.set(self.variable.get(), from_variable_callback=True) + + def set(self, value: str, from_variable_callback: bool = False): + self.current_value = value + + if self.text_label is not None: + self.text_label.configure(text=self.current_value) + else: + self.draw() + + if self.variable is not None and not from_variable_callback: + self.variable_callback_blocked = True + self.variable.set(self.current_value) + self.variable_callback_blocked = False + + def get(self) -> str: + return self.current_value + def clicked(self, event=0): if self.state is not tkinter.DISABLED: self.open_dropdown_menu() @@ -265,4 +298,7 @@ class CTkOptionMenu(CTkBaseClass): self.after(100, self.click_animation) if self.function is not None: - self.function() + try: + self.function() + except Exception: + pass diff --git a/examples/simple_example.py b/examples/simple_example.py index 8e054c3..f4cfa47 100644 --- a/examples/simple_example.py +++ b/examples/simple_example.py @@ -1,7 +1,7 @@ import tkinter import customtkinter -customtkinter.set_appearance_mode("dark") # Modes: "System" (standard), "Dark", "Light" +customtkinter.set_appearance_mode("light") # Modes: "System" (standard), "Dark", "Light" customtkinter.set_default_color_theme("blue") # Themes: "blue" (standard), "green", "dark-blue" app = customtkinter.CTk() # create CTk window like you do with the Tk window @@ -42,6 +42,9 @@ slider_1.set(0.5) entry_1 = customtkinter.CTkEntry(master=frame_1, placeholder_text="CTkEntry") entry_1.pack(pady=y_padding, padx=10) +optionmenu_1 = customtkinter.CTkOptionMenu(master=frame_1, values=["Option 1", "Option 2", "Option 3"]) +optionmenu_1.pack(pady=y_padding, padx=10) + checkbox_1 = customtkinter.CTkCheckBox(master=frame_1, command=check_box_function) checkbox_1.pack(pady=y_padding, padx=10) diff --git a/setup.cfg b/setup.cfg index 631c2d5..5cdbd1a 100644 --- a/setup.cfg +++ b/setup.cfg @@ -2,7 +2,7 @@ name = customtkinter version = 4.1.0 description = Create modern looking GUIs with Python -long_description = file: Readme.md +long_description = '# CustomTkinter UI-Library\nhttps://github.com/TomSchimansky/CustomTkinter/blob/master/documentation_images/Windows_dark.png\n\nMore Information: https://github.com/TomSchimansky/CustomTkinter' long_description_content_type = text/markdown url = https://github.com/TomSchimansky/CustomTkinter author = Tom Schimansky diff --git a/test/manual_integration_tests/test_tk_variables.py b/test/manual_integration_tests/test_tk_variables.py index 7b9d7bf..5f66c93 100644 --- a/test/manual_integration_tests/test_tk_variables.py +++ b/test/manual_integration_tests/test_tk_variables.py @@ -5,7 +5,7 @@ TEST_CONFIGURE = True TEST_REMOVING = False app = customtkinter.CTk() # create CTk window like you do with the Tk window (you can also use normal tkinter.Tk window) -app.geometry("400x600") +app.geometry("400x800") app.title("Tkinter Variable Test") txt_var = tkinter.StringVar(value="") @@ -69,6 +69,12 @@ switch_1 = customtkinter.CTkSwitch(master=app, variable=s_var, textvariable=s_va switch_1.pack(pady=20, padx=10) switch_1 = customtkinter.CTkSwitch(master=app, variable=s_var, textvariable=s_var, onvalue="on", offvalue="off") switch_1.pack(pady=20, padx=10) -#switch_1.toggle() + +optionmenu_var = tkinter.StringVar(value="test") +optionmenu_1 = customtkinter.CTkOptionMenu(master=app, variable=optionmenu_var, values=["Option 1", "Option 2", "Option 3"]) +optionmenu_1.pack(pady=20, padx=10) +optionmenu_2 = customtkinter.CTkOptionMenu(master=app, values=["Option 1", "Option 2", "Option 3"]) +optionmenu_2.pack(pady=20, padx=10) +optionmenu_2.configure(variable=optionmenu_var) app.mainloop()