From 7cb8f64dec71e81067b742bef7c8d3e81dff5a7f Mon Sep 17 00:00:00 2001 From: Tom Schimansky Date: Sat, 21 Jan 2023 14:22:18 +0100 Subject: [PATCH] fix switch and radiobutton background color #867, check if user set titlebar icon on Windows --- customtkinter/windows/ctk_tk.py | 34 ++++++++++++------- customtkinter/windows/ctk_toplevel.py | 23 +++++++++++-- .../windows/widgets/ctk_radiobutton.py | 1 + customtkinter/windows/widgets/ctk_switch.py | 19 +++++++---- 4 files changed, 57 insertions(+), 20 deletions(-) diff --git a/customtkinter/windows/ctk_tk.py b/customtkinter/windows/ctk_tk.py index 61e5609..ac56289 100644 --- a/customtkinter/windows/ctk_tk.py +++ b/customtkinter/windows/ctk_tk.py @@ -40,14 +40,6 @@ class CTk(tkinter.Tk, CTkAppearanceModeBaseClass, CTkScalingBaseClass): CTkScalingBaseClass.__init__(self, scaling_type="window") check_kwargs_empty(kwargs, raise_error=True) - try: - # Set Windows titlebar icon - if sys.platform.startswith("win"): - customtkinter_directory = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) - self.after(200, lambda: self.iconbitmap(os.path.join(customtkinter_directory, "assets", "icons", "CustomTkinter_icon_Windows.ico"))) - except Exception: - pass - self._current_width = 600 # initial window size, independent of scaling self._current_height = 500 self._min_width: int = 0 @@ -61,23 +53,28 @@ class CTk(tkinter.Tk, CTkAppearanceModeBaseClass, CTkScalingBaseClass): # set bg of tkinter.Tk super().configure(bg=self._apply_appearance_mode(self._fg_color)) - # set title and initial geometry + # set title self.title("CTk") - # self.geometry(f"{self._current_width}x{self._current_height}") + # indicator variables + self._iconbitmap_method_called = False # indicates if wm_iconbitmap method got called self._state_before_windows_set_titlebar_color = None self._window_exists = False # indicates if the window is already shown through update() or mainloop() after init self._withdraw_called_before_window_exists = False # indicates if withdraw() was called before window is first shown through update() or mainloop() self._iconify_called_before_window_exists = False # indicates if iconify() was called before window is first shown through update() or mainloop() + self._block_update_dimensions_event = False + # set CustomTkinter titlebar icon (Windows only) + if sys.platform.startswith("win"): + self.after(200, self._windows_set_titlebar_icon) + + # set titlebar color (Windows only) if sys.platform.startswith("win"): self._windows_set_titlebar_color(self._get_appearance_mode()) self.bind('', self._update_dimensions_event) self.bind('', self._focus_in_event) - self._block_update_dimensions_event = False - def destroy(self): self._disable_macos_dark_title_bar() @@ -219,6 +216,19 @@ class CTk(tkinter.Tk, CTkAppearanceModeBaseClass, CTkScalingBaseClass): else: return super().cget(attribute_name) + def wm_iconbitmap(self, bitmap=None, default=None): + self._iconbitmap_method_called = True + super().wm_iconbitmap(bitmap, default) + + def _windows_set_titlebar_icon(self): + try: + # if not the user already called iconbitmap method, set icon + if not self._iconbitmap_method_called: + customtkinter_directory = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + self.iconbitmap(os.path.join(customtkinter_directory, "assets", "icons", "CustomTkinter_icon_Windows.ico")) + except Exception: + pass + @classmethod def _enable_macos_dark_title_bar(cls): if sys.platform == "darwin" and not cls._deactivate_macos_window_header_manipulation: # macOS diff --git a/customtkinter/windows/ctk_toplevel.py b/customtkinter/windows/ctk_toplevel.py index a409a03..59b43f6 100644 --- a/customtkinter/windows/ctk_toplevel.py +++ b/customtkinter/windows/ctk_toplevel.py @@ -62,19 +62,25 @@ class CTkToplevel(tkinter.Toplevel, CTkAppearanceModeBaseClass, CTkScalingBaseCl # set title of tkinter.Toplevel super().title("CTkToplevel") + # indicator variables + self._iconbitmap_method_called = True self._state_before_windows_set_titlebar_color = None self._windows_set_titlebar_color_called = False # indicates if windows_set_titlebar_color was called, stays True until revert_withdraw_after_windows_set_titlebar_color is called self._withdraw_called_after_windows_set_titlebar_color = False # indicates if withdraw() was called after windows_set_titlebar_color self._iconify_called_after_windows_set_titlebar_color = False # indicates if iconify() was called after windows_set_titlebar_color + self._block_update_dimensions_event = False + # set CustomTkinter titlebar icon (Windows only) + if sys.platform.startswith("win"): + self.after(200, self._windows_set_titlebar_icon) + + # set titlebar color (Windows only) if sys.platform.startswith("win"): self._windows_set_titlebar_color(self._get_appearance_mode()) self.bind('', self._update_dimensions_event) self.bind('', self._focus_in_event) - self._block_update_dimensions_event = False - def destroy(self): self._disable_macos_dark_title_bar() @@ -190,6 +196,19 @@ class CTkToplevel(tkinter.Toplevel, CTkAppearanceModeBaseClass, CTkScalingBaseCl else: return super().cget(attribute_name) + def wm_iconbitmap(self, bitmap=None, default=None): + self._iconbitmap_method_called = True + super().wm_iconbitmap(bitmap, default) + + def _windows_set_titlebar_icon(self): + try: + # if not the user already called iconbitmap method, set icon + if not self._iconbitmap_method_called: + customtkinter_directory = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + self.iconbitmap(os.path.join(customtkinter_directory, "assets", "icons", "CustomTkinter_icon_Windows.ico")) + except Exception: + pass + @classmethod def _enable_macos_dark_title_bar(cls): if sys.platform == "darwin" and not cls._deactivate_macos_window_header_manipulation: # macOS diff --git a/customtkinter/windows/widgets/ctk_radiobutton.py b/customtkinter/windows/widgets/ctk_radiobutton.py index d5eba87..d797be9 100644 --- a/customtkinter/windows/widgets/ctk_radiobutton.py +++ b/customtkinter/windows/widgets/ctk_radiobutton.py @@ -85,6 +85,7 @@ class CTkRadioButton(CTkBaseClass): self.grid_columnconfigure(0, weight=0) self.grid_columnconfigure(1, weight=0, minsize=self._apply_widget_scaling(6)) self.grid_columnconfigure(2, weight=1) + self.grid_rowconfigure(0, weight=1) self._bg_canvas = CTkCanvas(master=self, highlightthickness=0, diff --git a/customtkinter/windows/widgets/ctk_switch.py b/customtkinter/windows/widgets/ctk_switch.py index cf3a9d2..6e8de13 100644 --- a/customtkinter/windows/widgets/ctk_switch.py +++ b/customtkinter/windows/widgets/ctk_switch.py @@ -92,6 +92,7 @@ class CTkSwitch(CTkBaseClass): self.grid_columnconfigure(0, weight=0) self.grid_columnconfigure(1, weight=0, minsize=self._apply_widget_scaling(6)) self.grid_columnconfigure(2, weight=1) + self.grid_rowconfigure(0, weight=1) self._bg_canvas = CTkCanvas(master=self, highlightthickness=0, @@ -221,23 +222,29 @@ class CTkSwitch(CTkBaseClass): self._canvas.configure(bg=self._apply_appearance_mode(self._bg_color)) if self._border_color == "transparent": - self._canvas.itemconfig("border_parts", fill=self._apply_appearance_mode(self._bg_color), + self._canvas.itemconfig("border_parts", + fill=self._apply_appearance_mode(self._bg_color), outline=self._apply_appearance_mode(self._bg_color)) else: - self._canvas.itemconfig("border_parts", fill=self._apply_appearance_mode(self._border_color), + self._canvas.itemconfig("border_parts", + fill=self._apply_appearance_mode(self._border_color), outline=self._apply_appearance_mode(self._border_color)) - self._canvas.itemconfig("inner_parts", fill=self._apply_appearance_mode(self._fg_color), + self._canvas.itemconfig("inner_parts", + fill=self._apply_appearance_mode(self._fg_color), outline=self._apply_appearance_mode(self._fg_color)) if self._progress_color == "transparent": - self._canvas.itemconfig("progress_parts", fill=self._apply_appearance_mode(self._fg_color), + self._canvas.itemconfig("progress_parts", + fill=self._apply_appearance_mode(self._fg_color), outline=self._apply_appearance_mode(self._fg_color)) else: - self._canvas.itemconfig("progress_parts", fill=self._apply_appearance_mode(self._progress_color), + self._canvas.itemconfig("progress_parts", + fill=self._apply_appearance_mode(self._progress_color), outline=self._apply_appearance_mode(self._progress_color)) - self._canvas.itemconfig("slider_parts", fill=self._apply_appearance_mode(self._button_color), + self._canvas.itemconfig("slider_parts", + fill=self._apply_appearance_mode(self._button_color), outline=self._apply_appearance_mode(self._button_color)) if self._state == tkinter.DISABLED: