From fef64638c8e433ad43d4bda9114f7fda0898a395 Mon Sep 17 00:00:00 2001 From: TomSchimansky Date: Sun, 22 May 2022 01:55:58 +0200 Subject: [PATCH] small fixes in CTkToplevel and CTkInputDialog --- customtkinter/__init__.py | 31 ++++++-- customtkinter/appearance_mode_tracker.py | 3 +- customtkinter/assets/themes/blue.json | 2 +- customtkinter/draw_engine.py | 75 +++++++++++------- customtkinter/scaling_tracker.py | 5 +- customtkinter/windows/ctk_input_dialog.py | 9 ++- customtkinter/windows/ctk_toplevel.py | 28 +++---- .../test_auto_resizing.py | 48 ----------- ...xample.py => test_scaling_simple_place.py} | 49 ++++-------- .../test_scaling_toplevel_pack.py | 79 +++++++++++++++++++ .../test_vertical_widgets.py | 5 +- 11 files changed, 195 insertions(+), 139 deletions(-) delete mode 100644 test/manual_integration_tests/test_auto_resizing.py rename test/manual_integration_tests/test_scaling/{simple_example.py => test_scaling_simple_place.py} (62%) create mode 100644 test/manual_integration_tests/test_scaling/test_scaling_toplevel_pack.py diff --git a/customtkinter/__init__.py b/customtkinter/__init__.py index bb88c14..4c33a57 100644 --- a/customtkinter/__init__.py +++ b/customtkinter/__init__.py @@ -12,7 +12,7 @@ from .font_manager import FontManager from .draw_engine import DrawEngine AppearanceModeTracker.init_appearance_mode() -ThemeManager.load_theme("blue") +ThemeManager.load_theme("blue") # load default theme FontManager.init_font_manager() # determine draw method based on current platform @@ -21,13 +21,14 @@ if sys.platform == "darwin": else: DrawEngine.preferred_drawing_method = "font_shapes" -# load Roboto fonts +# load Roboto fonts (used on Windows/Linux) script_directory = os.path.dirname(os.path.abspath(__file__)) FontManager.load_font(os.path.join(script_directory, "assets", "fonts", "Roboto", "Roboto-Regular.ttf")) FontManager.load_font(os.path.join(script_directory, "assets", "fonts", "Roboto", "Roboto-Medium.ttf")) -# load font necessary for rendering the widgets on Windows, Linux +# load font necessary for rendering the widgets (used on Windows/Linux) if FontManager.load_font(os.path.join(script_directory, "assets", "fonts", "CustomTkinter_shapes_font-fine.otf")) is False: + # change draw method if font loading failed if DrawEngine.preferred_drawing_method == "font_shapes": sys.stderr.write("customtkinter.__init__ warning: " + "Preferred drawing method 'font_shapes' can not be used because the font file could not be loaded.\n" + @@ -52,25 +53,39 @@ from .windows.ctk_toplevel import CTkToplevel from .windows.ctk_input_dialog import CTkInputDialog -def set_appearance_mode(mode_string): +def set_appearance_mode(mode_string: str): + """ possible values: light, dark, system """ AppearanceModeTracker.set_appearance_mode(mode_string) -def get_appearance_mode(): +def get_appearance_mode() -> str: + """ get current state of the appearance mode (light or dark) """ if AppearanceModeTracker.appearance_mode == 0: return "Light" elif AppearanceModeTracker.appearance_mode == 1: return "Dark" -def set_default_color_theme(color_string): +def set_default_color_theme(color_string: str): + """ set color theme or load custom theme file by passing the path """ ThemeManager.load_theme(color_string) -def set_user_scaling(scaling_value: float): - ScalingTracker.set_spacing_scaling(scaling_value) +def set_widget_scaling(scaling_value: float): + """ set scaling for the widget dimensions """ ScalingTracker.set_widget_scaling(scaling_value) +def set_spacing_scaling(scaling_value: float): + """ set scaling for geometry manager calls (place, pack, grid)""" + ScalingTracker.set_spacing_scaling(scaling_value) + + +def set_window_scaling(scaling_value: float): + """ set scaling for window dimensions """ + ScalingTracker.set_window_scaling(scaling_value) + + def deactivate_automatic_dpi_awareness(): + """ deactivate DPI awareness of current process (windll.shcore.SetProcessDpiAwareness(0)) """ ScalingTracker.deactivate_automatic_dpi_awareness = False diff --git a/customtkinter/appearance_mode_tracker.py b/customtkinter/appearance_mode_tracker.py index 7a9c98f..91a228e 100644 --- a/customtkinter/appearance_mode_tracker.py +++ b/customtkinter/appearance_mode_tracker.py @@ -21,6 +21,7 @@ class AppearanceModeTracker: callback_list = [] root_tk_list = [] update_loop_running = False + update_loop_interval = 500 # milliseconds appearance_mode_set_by = "system" appearance_mode = 0 # Light (standard) @@ -98,7 +99,7 @@ class AppearanceModeTracker: # find an existing tkinter.Tk object for the next call of .after() for root_tk in cls.root_tk_list: try: - root_tk.after(500, cls.update) + root_tk.after(cls.update_loop_interval, cls.update) return except Exception: continue diff --git a/customtkinter/assets/themes/blue.json b/customtkinter/assets/themes/blue.json index 597adae..8ca41b9 100644 --- a/customtkinter/assets/themes/blue.json +++ b/customtkinter/assets/themes/blue.json @@ -10,7 +10,7 @@ "entry_border": ["gray70", "gray32"], "entry_placeholder_text": ["gray52", "gray62"], "frame_border": ["#A7C2E0", "#5FB4DD"], - "frame_low": ["#E3E4E5", "gray18"], + "frame_low": ["#E3E4E5", "gray16"], "frame_high": ["#D7D8D9", "gray22"], "label": [null, null], "text": ["gray20", "#D5D9DE"], diff --git a/customtkinter/draw_engine.py b/customtkinter/draw_engine.py index 65eefbe..bcbc1ae 100644 --- a/customtkinter/draw_engine.py +++ b/customtkinter/draw_engine.py @@ -92,13 +92,13 @@ class DrawEngine: self._canvas.coords("border_line_1", (corner_radius, - corner_radius, - width - corner_radius, - corner_radius, - width - corner_radius, - height - corner_radius, - corner_radius, - height - corner_radius)) + corner_radius, + width - corner_radius, + corner_radius, + width - corner_radius, + height - corner_radius, + corner_radius, + height - corner_radius)) self._canvas.itemconfig("border_line_1", joinstyle=tkinter.ROUND, width=corner_radius * 2) @@ -157,7 +157,7 @@ class DrawEngine: self._canvas.delete("border_oval_2_a", "border_oval_2_b") if not self._canvas.find_withtag("border_oval_3_a") and height > 2 * corner_radius \ - and width > 2 * corner_radius and "border_oval_3" not in exclude_parts: + and width > 2 * corner_radius and "border_oval_3" not in exclude_parts: self._canvas.create_aa_circle(0, 0, 0, tags=("border_oval_3_a", "border_corner_part", "border_parts"), anchor=tkinter.CENTER) self._canvas.create_aa_circle(0, 0, 0, tags=("border_oval_3_b", "border_corner_part", "border_parts"), anchor=tkinter.CENTER, angle=180) requires_recoloring = True @@ -217,12 +217,12 @@ class DrawEngine: self._canvas.delete("inner_oval_2_a", "inner_oval_2_b") if not self._canvas.find_withtag("inner_oval_3_a") and height - (2 * border_width) > 2 * inner_corner_radius \ - and width - (2 * border_width) > 2 * inner_corner_radius and "inner_oval_3" not in exclude_parts: + and width - (2 * border_width) > 2 * inner_corner_radius and "inner_oval_3" not in exclude_parts: self._canvas.create_aa_circle(0, 0, 0, tags=("inner_oval_3_a", "inner_corner_part", "inner_parts"), anchor=tkinter.CENTER) self._canvas.create_aa_circle(0, 0, 0, tags=("inner_oval_3_b", "inner_corner_part", "inner_parts"), anchor=tkinter.CENTER, angle=180) requires_recoloring = True elif self._canvas.find_withtag("inner_oval_3_a") and (not (height - (2 * border_width) > 2 * inner_corner_radius - and width - (2 * border_width) > 2 * inner_corner_radius) or "inner_oval_3" in exclude_parts): + and width - (2 * border_width) > 2 * inner_corner_radius) or "inner_oval_3" in exclude_parts): self._canvas.delete("inner_oval_3_a", "inner_oval_3_b") if not self._canvas.find_withtag("inner_oval_4_a") and height - (2 * border_width) > 2 * inner_corner_radius and "inner_oval_4" not in exclude_parts: @@ -341,7 +341,7 @@ class DrawEngine: height - border_width)) self._canvas.coords("inner_rectangle_2", (border_width, border_width + inner_corner_radius, - width - border_width , + width - border_width, height - inner_corner_radius - border_width)) return requires_recoloring @@ -462,9 +462,9 @@ class DrawEngine: border_width + inner_corner_radius, inner_corner_radius) self._canvas.coords("progress_oval_2_b", border_width + inner_corner_radius + (width - 2 * border_width - 2 * inner_corner_radius) * progress_value, border_width + inner_corner_radius, inner_corner_radius) - self._canvas.coords("progress_oval_3_a", border_width + inner_corner_radius + (width - 2 * border_width - 2 * inner_corner_radius) * progress_value, + self._canvas.coords("progress_oval_3_a", border_width + inner_corner_radius + (width - 2 * border_width - 2 * inner_corner_radius) * progress_value, height - border_width - inner_corner_radius, inner_corner_radius) - self._canvas.coords("progress_oval_3_b", border_width + inner_corner_radius + (width - 2 * border_width - 2 * inner_corner_radius) * progress_value, + self._canvas.coords("progress_oval_3_b", border_width + inner_corner_radius + (width - 2 * border_width - 2 * inner_corner_radius) * progress_value, height - border_width - inner_corner_radius, inner_corner_radius) self._canvas.coords("progress_oval_4_a", border_width + inner_corner_radius, height - border_width - inner_corner_radius, inner_corner_radius) self._canvas.coords("progress_oval_4_b", border_width + inner_corner_radius, height - border_width - inner_corner_radius, inner_corner_radius) @@ -631,22 +631,41 @@ class DrawEngine: self._canvas.delete("slider_rectangle_2") # set positions of circles and rectangles - slider_x_position = corner_radius + (button_length / 2) + (width - 2 * corner_radius - button_length) * slider_value - self._canvas.coords("slider_oval_1_a", slider_x_position - (button_length / 2), button_corner_radius, button_corner_radius) - self._canvas.coords("slider_oval_1_b", slider_x_position - (button_length / 2), button_corner_radius, button_corner_radius) - self._canvas.coords("slider_oval_2_a", slider_x_position + (button_length / 2), button_corner_radius, button_corner_radius) - self._canvas.coords("slider_oval_2_b", slider_x_position + (button_length / 2), button_corner_radius, button_corner_radius) - self._canvas.coords("slider_oval_3_a", slider_x_position + (button_length / 2), height - button_corner_radius, button_corner_radius) - self._canvas.coords("slider_oval_3_b", slider_x_position + (button_length / 2), height - button_corner_radius, button_corner_radius) - self._canvas.coords("slider_oval_4_a", slider_x_position - (button_length / 2), height - button_corner_radius, button_corner_radius) - self._canvas.coords("slider_oval_4_b", slider_x_position - (button_length / 2), height - button_corner_radius, button_corner_radius) + if orientation == "w": + slider_x_position = corner_radius + (button_length / 2) + (width - 2 * corner_radius - button_length) * slider_value + self._canvas.coords("slider_oval_1_a", slider_x_position - (button_length / 2), button_corner_radius, button_corner_radius) + self._canvas.coords("slider_oval_1_b", slider_x_position - (button_length / 2), button_corner_radius, button_corner_radius) + self._canvas.coords("slider_oval_2_a", slider_x_position + (button_length / 2), button_corner_radius, button_corner_radius) + self._canvas.coords("slider_oval_2_b", slider_x_position + (button_length / 2), button_corner_radius, button_corner_radius) + self._canvas.coords("slider_oval_3_a", slider_x_position + (button_length / 2), height - button_corner_radius, button_corner_radius) + self._canvas.coords("slider_oval_3_b", slider_x_position + (button_length / 2), height - button_corner_radius, button_corner_radius) + self._canvas.coords("slider_oval_4_a", slider_x_position - (button_length / 2), height - button_corner_radius, button_corner_radius) + self._canvas.coords("slider_oval_4_b", slider_x_position - (button_length / 2), height - button_corner_radius, button_corner_radius) - self._canvas.coords("slider_rectangle_1", - slider_x_position - (button_length / 2), 0, - slider_x_position + (button_length / 2), height) - self._canvas.coords("slider_rectangle_2", - slider_x_position - (button_length / 2) - button_corner_radius, button_corner_radius, - slider_x_position + (button_length / 2) + button_corner_radius, height - button_corner_radius) + self._canvas.coords("slider_rectangle_1", + slider_x_position - (button_length / 2), 0, + slider_x_position + (button_length / 2), height) + self._canvas.coords("slider_rectangle_2", + slider_x_position - (button_length / 2) - button_corner_radius, button_corner_radius, + slider_x_position + (button_length / 2) + button_corner_radius, height - button_corner_radius) + + elif orientation == "s": + slider_y_position = corner_radius + (button_length / 2) + (height - 2 * corner_radius - button_length) * (1 - slider_value) + self._canvas.coords("slider_oval_1_a", button_corner_radius, slider_y_position - (button_length / 2), button_corner_radius) + self._canvas.coords("slider_oval_1_b", button_corner_radius, slider_y_position - (button_length / 2), button_corner_radius) + self._canvas.coords("slider_oval_2_a", button_corner_radius, slider_y_position + (button_length / 2), button_corner_radius) + self._canvas.coords("slider_oval_2_b", button_corner_radius, slider_y_position + (button_length / 2), button_corner_radius) + self._canvas.coords("slider_oval_3_a", width - button_corner_radius, slider_y_position + (button_length / 2), button_corner_radius) + self._canvas.coords("slider_oval_3_b", width - button_corner_radius, slider_y_position + (button_length / 2), button_corner_radius) + self._canvas.coords("slider_oval_4_a", width - button_corner_radius, slider_y_position - (button_length / 2), button_corner_radius) + self._canvas.coords("slider_oval_4_b", width - button_corner_radius, slider_y_position - (button_length / 2), button_corner_radius) + + self._canvas.coords("slider_rectangle_1", + 0, slider_y_position - (button_length / 2), + width, slider_y_position + (button_length / 2)) + self._canvas.coords("slider_rectangle_2", + button_corner_radius, slider_y_position - (button_length / 2) - button_corner_radius, + width - button_corner_radius, slider_y_position + (button_length / 2) + button_corner_radius) if requires_recoloring: # new parts were added -> manage z-order self._canvas.tag_raise("slider_parts") diff --git a/customtkinter/scaling_tracker.py b/customtkinter/scaling_tracker.py index 2609d2a..9f33e41 100644 --- a/customtkinter/scaling_tracker.py +++ b/customtkinter/scaling_tracker.py @@ -14,6 +14,7 @@ class ScalingTracker: spacing_scaling = 1 update_loop_running = False + update_loop_interval = 150 # milliseconds @classmethod def get_widget_scaling(cls, widget) -> float: @@ -160,8 +161,6 @@ class ScalingTracker: @classmethod def check_dpi_scaling(cls): # check for every window if scaling value changed - # (not implemented yet) - for window in cls.window_widgets_dict: current_dpi_scaling_value = cls.get_window_dpi_scaling(window) if current_dpi_scaling_value != cls.window_dpi_scaling_dict[window]: @@ -171,7 +170,7 @@ class ScalingTracker: # find an existing tkinter object for the next call of .after() for root_tk in cls.window_widgets_dict.keys(): try: - root_tk.after(200, cls.check_dpi_scaling) + root_tk.after(cls.update_loop_interval, cls.check_dpi_scaling) return except Exception: continue diff --git a/customtkinter/windows/ctk_input_dialog.py b/customtkinter/windows/ctk_input_dialog.py index ff2d442..bf38ad3 100644 --- a/customtkinter/windows/ctk_input_dialog.py +++ b/customtkinter/windows/ctk_input_dialog.py @@ -27,6 +27,7 @@ class CTkInputDialog: self.height = len(text.split("\n"))*20 + 150 + self.text = text self.window_bg_color = ThemeManager.theme["color"]["window_bg_color"] self.fg_color = ThemeManager.theme["color"]["button"] if fg_color == "default_theme" else fg_color self.hover_color = ThemeManager.theme["color"]["button_hover"] if hover_color == "default_theme" else hover_color @@ -34,12 +35,16 @@ class CTkInputDialog: self.top = CTkToplevel() self.top.geometry(f"{280}x{self.height}") - self.top.resizable(False, False) + self.top.minsize(280, self.height) + self.top.maxsize(280, self.height) self.top.title(title) self.top.lift() self.top.focus_force() self.top.grab_set() + self.top.after(10, self.create_widgets) # create widgets with slight delay, to avoid white flickering of background + + def create_widgets(self): self.label_frame = CTkFrame(master=self.top, corner_radius=0, fg_color=self.window_bg_color, @@ -55,7 +60,7 @@ class CTkInputDialog: self.button_and_entry_frame.place(relx=0.5, rely=1, anchor=tkinter.S) self.myLabel = CTkLabel(master=self.label_frame, - text=text, + text=self.text, width=300, fg_color=None, height=self.height-100) diff --git a/customtkinter/windows/ctk_toplevel.py b/customtkinter/windows/ctk_toplevel.py index a2f83be..a8954eb 100644 --- a/customtkinter/windows/ctk_toplevel.py +++ b/customtkinter/windows/ctk_toplevel.py @@ -26,8 +26,8 @@ class CTkToplevel(tkinter.Toplevel): ScalingTracker.add_widget(self.set_scaling, self) self.window_scaling = ScalingTracker.get_window_scaling(self) - self.current_width = 600 # initial window size, always without scaling - self.current_height = 500 + self.current_width = 200 # initial window size, always without scaling + self.current_height = 200 self.min_width: int = 0 self.min_height: int = 0 self.max_width: int = 1_000_000 @@ -47,6 +47,7 @@ class CTkToplevel(tkinter.Toplevel): AppearanceModeTracker.add(self.set_appearance_mode, self) super().configure(bg=ThemeManager.single_color(self.fg_color, self.appearance_mode)) super().title("CTkToplevel") + # self.geometry(f"{self.current_width}x{self.current_height}") if sys.platform.startswith("win"): if self.appearance_mode == 1: @@ -54,6 +55,8 @@ class CTkToplevel(tkinter.Toplevel): else: self.windows_set_titlebar_color("light") + self.bind('', self.update_dimensions_event) + def update_dimensions_event(self, event=None): detected_width = self.winfo_width() # detect current window size detected_height = self.winfo_height() @@ -65,20 +68,17 @@ class CTkToplevel(tkinter.Toplevel): def set_scaling(self, new_widget_scaling, new_spacing_scaling, new_window_scaling): self.window_scaling = new_window_scaling - # reset min, max and resizable constraints for applying scaling - if self.last_resizable_args is not None: - super().resizable(True, True) - if self.min_width is not None or self.min_height is not None: - super().minsize(0, 0) - if self.max_width is not None or self.max_height is not None: - super().maxsize(1_000_000, 1_000_000) + # force new dimensions on window by using min, max, and geometry + super().minsize(self.apply_window_scaling(self.current_width), self.apply_window_scaling(self.current_height)) + super().maxsize(self.apply_window_scaling(self.current_width), self.apply_window_scaling(self.current_height)) + super().geometry( + f"{self.apply_window_scaling(self.current_width)}x" + f"{self.apply_window_scaling(self.current_height)}") + print("set_scaling:", self.apply_window_scaling(self.current_width), self.max_width, self.min_width) - # set new window size by applying scaling to the current window size - self.geometry(f"{self.current_width}x{self.current_height}") + # set new scaled min and max with 400ms delay (otherwise it won't work for some reason) + self.after(400, self.set_scaled_min_max) - # set scaled min, max sizes and reapply resizable - if self.last_resizable_args is not None: - super().resizable(*self.last_resizable_args[0], **self.last_resizable_args[1]) # args, kwargs + def set_scaled_min_max(self): if self.min_width is not None or self.min_height is not None: super().minsize(self.apply_window_scaling(self.min_width), self.apply_window_scaling(self.min_height)) if self.max_width is not None or self.max_height is not None: diff --git a/test/manual_integration_tests/test_auto_resizing.py b/test/manual_integration_tests/test_auto_resizing.py deleted file mode 100644 index e72afbf..0000000 --- a/test/manual_integration_tests/test_auto_resizing.py +++ /dev/null @@ -1,48 +0,0 @@ -import tkinter -import customtkinter # <- import the CustomTkinter module -from PIL import Image, ImageTk # <- import PIL for the images -import os - -PATH = os.path.dirname(os.path.realpath(__file__)) - -customtkinter.set_appearance_mode("System") # Other: "Dark", "Light" - -root_tk = customtkinter.CTk() # create CTk window like you do with the Tk window (you can also use normal tkinter.Tk window) -root_tk.geometry("400x600") -root_tk.title("CustomTkinter Test") - - -def button_function(): - print("button pressed") - - -# load images as PhotoImage -settings_image = ImageTk.PhotoImage(Image.open(PATH + "/test_images/settings.png").resize((40, 40))) -bell_image = ImageTk.PhotoImage(Image.open(PATH + "/test_images/bell.png").resize((40, 40))) - -frame_1 = customtkinter.CTkFrame(master=root_tk, width=300, height=350) -frame_1.place(relx=0.5, rely=0.5, relwidth=0.8, relheight=0.8, anchor=tkinter.CENTER) - -# button with bell-image and standard compound ("left") -button_2 = customtkinter.CTkButton(master=frame_1, height=60, - corner_radius=10, command=button_function) -button_2.place(relx=0.5, rely=0.3, relwidth=0.5, anchor=tkinter.CENTER) -button_2.configure(image=bell_image) -button_2.configure(image=settings_image, text="new text") - -# button with settings-image and compound="right" -button_3 = customtkinter.CTkButton(master=frame_1, text="large button 3", compound="right", - command=button_function, height=30, corner_radius=8) -button_3.place(relx=0.5, rely=0.5, relwidth=0.6, anchor=tkinter.CENTER) - -entry_1 = customtkinter.CTkEntry(frame_1) -entry_1.pack(fill="x", pady=10, padx=10) -entry_1.configure(corner_radius=15) - -label_1 = customtkinter.CTkLabel(frame_1, text="auto size label") -label_1.place(relx=0.5, rely=0.85, anchor=tkinter.CENTER, relwidth=0.5, relheight=0.08) - -entry_2 = customtkinter.CTkEntry(frame_1, corner_radius=6, height=30, width=90, justify='center') -entry_2.place(relx=0.5, anchor=tkinter.CENTER, rely=0.15) - -root_tk.mainloop() diff --git a/test/manual_integration_tests/test_scaling/simple_example.py b/test/manual_integration_tests/test_scaling/test_scaling_simple_place.py similarity index 62% rename from test/manual_integration_tests/test_scaling/simple_example.py rename to test/manual_integration_tests/test_scaling/test_scaling_simple_place.py index 6afb23e..72a5deb 100644 --- a/test/manual_integration_tests/test_scaling/simple_example.py +++ b/test/manual_integration_tests/test_scaling/test_scaling_simple_place.py @@ -7,12 +7,12 @@ customtkinter.set_appearance_mode("dark") # Modes: "System" (standard), "Dark", customtkinter.set_default_color_theme("blue") # Themes: "blue" (standard), "green", "dark-blue" root_tk = customtkinter.CTk() # create CTk window like you do with the Tk window (you can also use normal tkinter.Tk window) -root_tk.geometry("400x480") +root_tk.geometry("400x600") root_tk.title("CustomTkinter manual scaling test") #root_tk.minsize(200, 200) #root_tk.maxsize(520, 520) -root_tk.resizable(True, False) +#root_tk.resizable(True, False) def button_function(): @@ -21,51 +21,36 @@ def button_function(): def slider_function(value): - customtkinter.set_user_scaling(value * 2) - customtkinter.ScalingTracker.set_window_scaling(value * 2) + customtkinter.set_widget_scaling(value * 2) + customtkinter.set_spacing_scaling(value * 2) + customtkinter.set_window_scaling(value * 2) progressbar_1.set(value) -def check_box_function(): - print("checkbox_1:", checkbox_1.get()) - - y_padding = 13 -frame_1 = customtkinter.CTkFrame(master=root_tk) -frame_1.pack(pady=20, padx=60, fill="both", expand=True) - +frame_1 = customtkinter.CTkFrame(master=root_tk, height=550, width=300) +frame_1.place(relx=0.5, rely=0.5, anchor=tkinter.CENTER) label_1 = customtkinter.CTkLabel(master=frame_1, justify=tkinter.LEFT) -label_1.pack(pady=y_padding, padx=10) - +label_1.place(relx=0.5, y=50, anchor=tkinter.CENTER) progressbar_1 = customtkinter.CTkProgressBar(master=frame_1) -progressbar_1.pack(pady=y_padding, padx=10) - +progressbar_1.place(relx=0.5, y=100, anchor=tkinter.CENTER) button_1 = customtkinter.CTkButton(master=frame_1, corner_radius=8, command=button_function) -button_1.pack(pady=y_padding, padx=10) -# button_1.configure(state="disabled") - +button_1.place(relx=0.5, y=150, anchor=tkinter.CENTER) slider_1 = customtkinter.CTkSlider(master=frame_1, command=slider_function, from_=0, to=1) -slider_1.pack(pady=y_padding, padx=10) +slider_1.place(relx=0.5, y=200, anchor=tkinter.CENTER) slider_1.set(0.5) - entry_1 = customtkinter.CTkEntry(master=frame_1, placeholder_text="CTkEntry") -entry_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) - +entry_1.place(relx=0.5, y=250, anchor=tkinter.CENTER) +checkbox_1 = customtkinter.CTkCheckBox(master=frame_1) +checkbox_1.place(relx=0.5, y=300, anchor=tkinter.CENTER) radiobutton_var = tkinter.IntVar(value=1) - radiobutton_1 = customtkinter.CTkRadioButton(master=frame_1, variable=radiobutton_var, value=1) -radiobutton_1.pack(pady=y_padding, padx=10) - +radiobutton_1.place(relx=0.5, y=350, anchor=tkinter.CENTER) radiobutton_2 = customtkinter.CTkRadioButton(master=frame_1, variable=radiobutton_var, value=2) -radiobutton_2.pack(pady=y_padding, padx=10) - +radiobutton_2.place(relx=0.5, y=400, anchor=tkinter.CENTER) s_var = tkinter.StringVar(value="on") - switch_1 = customtkinter.CTkSwitch(master=frame_1) -switch_1.pack(pady=y_padding, padx=10) +switch_1.place(relx=0.5, y=450, anchor=tkinter.CENTER) root_tk.mainloop() diff --git a/test/manual_integration_tests/test_scaling/test_scaling_toplevel_pack.py b/test/manual_integration_tests/test_scaling/test_scaling_toplevel_pack.py new file mode 100644 index 0000000..6c29373 --- /dev/null +++ b/test/manual_integration_tests/test_scaling/test_scaling_toplevel_pack.py @@ -0,0 +1,79 @@ +import tkinter +import customtkinter # <- import the CustomTkinter module + +customtkinter.ScalingTracker.set_window_scaling(0.5) + +customtkinter.set_appearance_mode("dark") # Modes: "System" (standard), "Dark", "Light" +customtkinter.set_default_color_theme("blue") # Themes: "blue" (standard), "green", "dark-blue" + +root_tk = customtkinter.CTk() # create CTk window like you do with the Tk window (you can also use normal tkinter.Tk window) +root_tk.geometry("400x480") +root_tk.title("CustomTkinter manual scaling test") + +top_tk = customtkinter.CTkToplevel(root_tk) + +#root_tk.minsize(200, 200) +#root_tk.maxsize(520, 520) +#root_tk.resizable(True, False) + + +def button_function(): + root_tk.geometry(f"{200}x{200}") + print("Button click", label_1.text_label.cget("text")) + + +def slider_function(value): + customtkinter.set_widget_scaling(value * 2) + customtkinter.ScalingTracker.set_window_scaling(value * 2) + progressbar_1.set(value) + + +y_padding = 13 + +frame_1 = customtkinter.CTkFrame(master=root_tk) +frame_1.pack(pady=20, padx=60, fill="both", expand=True) +label_1 = customtkinter.CTkLabel(master=frame_1, justify=tkinter.LEFT) +label_1.pack(pady=y_padding, padx=10) +progressbar_1 = customtkinter.CTkProgressBar(master=frame_1) +progressbar_1.pack(pady=y_padding, padx=10) +button_1 = customtkinter.CTkButton(master=frame_1, corner_radius=8, command=button_function) +button_1.pack(pady=y_padding, padx=10) +slider_1 = customtkinter.CTkSlider(master=frame_1, command=slider_function, from_=0, to=1) +slider_1.pack(pady=y_padding, padx=10) +slider_1.set(0.5) +entry_1 = customtkinter.CTkEntry(master=frame_1, placeholder_text="CTkEntry") +entry_1.pack(pady=y_padding, padx=10) +checkbox_1 = customtkinter.CTkCheckBox(master=frame_1) +checkbox_1.pack(pady=y_padding, padx=10) +radiobutton_var = tkinter.IntVar(value=1) +radiobutton_1 = customtkinter.CTkRadioButton(master=frame_1, variable=radiobutton_var, value=1) +radiobutton_1.pack(pady=y_padding, padx=10) +radiobutton_2 = customtkinter.CTkRadioButton(master=frame_1, variable=radiobutton_var, value=2) +radiobutton_2.pack(pady=y_padding, padx=10) +s_var = tkinter.StringVar(value="on") +switch_1 = customtkinter.CTkSwitch(master=frame_1) +switch_1.pack(pady=y_padding, padx=10) + + +label_1 = customtkinter.CTkLabel(master=top_tk, justify=tkinter.LEFT) +label_1.pack(pady=y_padding, padx=10) +progressbar_1 = customtkinter.CTkProgressBar(master=top_tk) +progressbar_1.pack(pady=y_padding, padx=10) +button_1 = customtkinter.CTkButton(master=top_tk, corner_radius=8, command=button_function) +button_1.pack(pady=y_padding, padx=10) +slider_1 = customtkinter.CTkSlider(master=top_tk, command=slider_function, from_=0, to=1) +slider_1.pack(pady=y_padding, padx=10) +slider_1.set(0.5) +entry_1 = customtkinter.CTkEntry(master=top_tk, placeholder_text="CTkEntry") +entry_1.pack(pady=y_padding, padx=10) +checkbox_1 = customtkinter.CTkCheckBox(master=top_tk) +checkbox_1.pack(pady=y_padding, padx=10) +radiobutton_var = tkinter.IntVar(value=1) +radiobutton_1 = customtkinter.CTkRadioButton(master=top_tk, variable=radiobutton_var, value=1) +radiobutton_1.pack(pady=y_padding, padx=10) +radiobutton_2 = customtkinter.CTkRadioButton(master=top_tk, variable=radiobutton_var, value=2) +radiobutton_2.pack(pady=y_padding, padx=10) +switch_1 = customtkinter.CTkSwitch(master=top_tk) +switch_1.pack(pady=y_padding, padx=10) + +root_tk.mainloop() diff --git a/test/manual_integration_tests/test_vertical_widgets.py b/test/manual_integration_tests/test_vertical_widgets.py index 775419c..77d51e0 100644 --- a/test/manual_integration_tests/test_vertical_widgets.py +++ b/test/manual_integration_tests/test_vertical_widgets.py @@ -13,11 +13,12 @@ progressbar_1.grid(row=0, column=0, pady=20, padx=20) progressbar_2 = customtkinter.CTkProgressBar(root_tk, orient="vertical") progressbar_2.grid(row=1, column=0, pady=20, padx=20) -slider_1 = customtkinter.CTkSlider(root_tk, orient="horizontal", command=progressbar_1.set) +slider_1 = customtkinter.CTkSlider(root_tk, orient="horizontal", command=progressbar_1.set, + button_corner_radius=3, button_length=20) slider_1.grid(row=2, column=0, pady=20, padx=20) slider_2 = customtkinter.CTkSlider(root_tk, orient="vertical", command=progressbar_2.set, - button_corner_radius=2, button_length=20) + button_corner_radius=3, button_length=20) slider_2.grid(row=3, column=0, pady=20, padx=20)