diff --git a/customtkinter/__init__.py b/customtkinter/__init__.py index 3004e4d..216a377 100644 --- a/customtkinter/__init__.py +++ b/customtkinter/__init__.py @@ -1,4 +1,4 @@ -__version__ = "5.0.5" +__version__ = "5.1.2" import os import sys @@ -33,6 +33,7 @@ from .windows.widgets import CTkSlider from .windows.widgets import CTkSwitch from .windows.widgets import CTkTabview from .windows.widgets import CTkTextbox +from .windows.widgets import CTkScrollableFrame # import windows from .windows import CTk diff --git a/customtkinter/__pycache__/__init__.cpython-310.pyc b/customtkinter/__pycache__/__init__.cpython-310.pyc index 56e450c..271ac21 100644 Binary files a/customtkinter/__pycache__/__init__.cpython-310.pyc and b/customtkinter/__pycache__/__init__.cpython-310.pyc differ diff --git a/customtkinter/__pycache__/__init__.cpython-37.pyc b/customtkinter/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000..d651e83 Binary files /dev/null and b/customtkinter/__pycache__/__init__.cpython-37.pyc differ diff --git a/customtkinter/assets/.DS_Store b/customtkinter/assets/.DS_Store deleted file mode 100644 index 1056a75..0000000 Binary files a/customtkinter/assets/.DS_Store and /dev/null differ diff --git a/customtkinter/assets/icons/.DS_Store b/customtkinter/assets/icons/.DS_Store deleted file mode 100644 index 57d1d87..0000000 Binary files a/customtkinter/assets/icons/.DS_Store and /dev/null differ diff --git a/customtkinter/assets/themes/blue.json b/customtkinter/assets/themes/blue.json index 73a1f4d..838e26b 100644 --- a/customtkinter/assets/themes/blue.json +++ b/customtkinter/assets/themes/blue.json @@ -127,6 +127,9 @@ "scrollbar_button_color": ["gray55", "gray41"], "scrollbar_button_hover_color": ["gray40", "gray53"] }, + "CTkScrollableFrame": { + "label_fg_color": ["gray78", "gray23"] + }, "DropdownMenu": { "fg_color": ["gray90", "gray20"], "hover_color": ["gray75", "gray28"], diff --git a/customtkinter/assets/themes/dark-blue.json b/customtkinter/assets/themes/dark-blue.json index 1ecf8ab..b418cbf 100644 --- a/customtkinter/assets/themes/dark-blue.json +++ b/customtkinter/assets/themes/dark-blue.json @@ -127,6 +127,9 @@ "scrollbar_button_color": ["gray55", "gray41"], "scrollbar_button_hover_color": ["gray40", "gray53"] }, + "CTkScrollableFrame": { + "label_fg_color": ["gray80", "gray21"] + }, "DropdownMenu": { "fg_color": ["gray90", "gray20"], "hover_color": ["gray75", "gray28"], diff --git a/customtkinter/assets/themes/green.json b/customtkinter/assets/themes/green.json index 14cd8c6..cefab6e 100644 --- a/customtkinter/assets/themes/green.json +++ b/customtkinter/assets/themes/green.json @@ -127,6 +127,9 @@ "scrollbar_button_color": ["gray55", "gray41"], "scrollbar_button_hover_color": ["gray40", "gray53"] }, + "CTkScrollableFrame": { + "label_fg_color": ["gray78", "gray23"] + }, "DropdownMenu": { "fg_color": ["gray90", "gray20"], "hover_color": ["gray75", "gray28"], diff --git a/customtkinter/windows/__pycache__/__init__.cpython-310.pyc b/customtkinter/windows/__pycache__/__init__.cpython-310.pyc index 624c913..8c9c8c7 100644 Binary files a/customtkinter/windows/__pycache__/__init__.cpython-310.pyc and b/customtkinter/windows/__pycache__/__init__.cpython-310.pyc differ diff --git a/customtkinter/windows/__pycache__/__init__.cpython-37.pyc b/customtkinter/windows/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000..6960c15 Binary files /dev/null and b/customtkinter/windows/__pycache__/__init__.cpython-37.pyc differ diff --git a/customtkinter/windows/__pycache__/ctk_input_dialog.cpython-310.pyc b/customtkinter/windows/__pycache__/ctk_input_dialog.cpython-310.pyc index c04083a..154023a 100644 Binary files a/customtkinter/windows/__pycache__/ctk_input_dialog.cpython-310.pyc and b/customtkinter/windows/__pycache__/ctk_input_dialog.cpython-310.pyc differ diff --git a/customtkinter/windows/__pycache__/ctk_tk.cpython-310.pyc b/customtkinter/windows/__pycache__/ctk_tk.cpython-310.pyc index 47b7858..e623320 100644 Binary files a/customtkinter/windows/__pycache__/ctk_tk.cpython-310.pyc and b/customtkinter/windows/__pycache__/ctk_tk.cpython-310.pyc differ diff --git a/customtkinter/windows/__pycache__/ctk_tk.cpython-37.pyc b/customtkinter/windows/__pycache__/ctk_tk.cpython-37.pyc new file mode 100644 index 0000000..2cb2e90 Binary files /dev/null and b/customtkinter/windows/__pycache__/ctk_tk.cpython-37.pyc differ diff --git a/customtkinter/windows/__pycache__/ctk_toplevel.cpython-310.pyc b/customtkinter/windows/__pycache__/ctk_toplevel.cpython-310.pyc index b50f981..6751407 100644 Binary files a/customtkinter/windows/__pycache__/ctk_toplevel.cpython-310.pyc and b/customtkinter/windows/__pycache__/ctk_toplevel.cpython-310.pyc differ diff --git a/customtkinter/windows/ctk_tk.py b/customtkinter/windows/ctk_tk.py index ac56289..cc3c940 100644 --- a/customtkinter/windows/ctk_tk.py +++ b/customtkinter/windows/ctk_tk.py @@ -64,6 +64,9 @@ class CTk(tkinter.Tk, CTkAppearanceModeBaseClass, CTkScalingBaseClass): 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 + # save focus before calling withdraw + self.focused_widget_before_widthdraw = None + # set CustomTkinter titlebar icon (Windows only) if sys.platform.startswith("win"): self.after(200, self._windows_set_titlebar_icon) @@ -137,24 +140,26 @@ class CTk(tkinter.Tk, CTkAppearanceModeBaseClass, CTkScalingBaseClass): def update(self): if self._window_exists is False: - self._window_exists = True - if sys.platform.startswith("win"): if not self._withdraw_called_before_window_exists and not self._iconify_called_before_window_exists: # print("window dont exists -> deiconify in update") self.deiconify() + self._window_exists = True + super().update() def mainloop(self, *args, **kwargs): if not self._window_exists: - self._window_exists = True - if sys.platform.startswith("win"): + self._windows_set_titlebar_color(self._get_appearance_mode()) + if not self._withdraw_called_before_window_exists and not self._iconify_called_before_window_exists: # print("window dont exists -> deiconify in mainloop") self.deiconify() + self._window_exists = True + super().mainloop(*args, **kwargs) def resizable(self, width: bool = None, height: bool = None): @@ -220,6 +225,10 @@ class CTk(tkinter.Tk, CTkAppearanceModeBaseClass, CTkScalingBaseClass): self._iconbitmap_method_called = True super().wm_iconbitmap(bitmap, default) + def 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 @@ -263,9 +272,11 @@ class CTk(tkinter.Tk, CTkAppearanceModeBaseClass, CTkScalingBaseClass): # print("window_exists -> state_before_windows_set_titlebar_color: ", self.state_before_windows_set_titlebar_color) if self._state_before_windows_set_titlebar_color != "iconic" or self._state_before_windows_set_titlebar_color != "withdrawn": + self.focused_widget_before_widthdraw = self.focus_get() super().withdraw() # hide window so that it can be redrawn after the titlebar change so that the color change is visible else: # print("window dont exists -> withdraw and update") + self.focused_widget_before_widthdraw = self.focus_get() super().withdraw() super().update() @@ -294,7 +305,7 @@ class CTk(tkinter.Tk, CTkAppearanceModeBaseClass, CTkScalingBaseClass): except Exception as err: print(err) - if self._window_exists: + if self._window_exists or True: # print("window_exists -> return to original state: ", self.state_before_windows_set_titlebar_color) if self._state_before_windows_set_titlebar_color == "normal": self.deiconify() @@ -307,6 +318,10 @@ class CTk(tkinter.Tk, CTkAppearanceModeBaseClass, CTkScalingBaseClass): else: pass # wait for update or mainloop to be called + if self.focused_widget_before_widthdraw is not None: + self.after(1, self.focused_widget_before_widthdraw.focus) + self.focused_widget_before_widthdraw = None + def _set_appearance_mode(self, mode_string: str): super()._set_appearance_mode(mode_string) diff --git a/customtkinter/windows/ctk_toplevel.py b/customtkinter/windows/ctk_toplevel.py index 59b43f6..a4eef57 100644 --- a/customtkinter/windows/ctk_toplevel.py +++ b/customtkinter/windows/ctk_toplevel.py @@ -70,6 +70,9 @@ class CTkToplevel(tkinter.Toplevel, CTkAppearanceModeBaseClass, CTkScalingBaseCl 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 + # save focus before calling withdraw + self.focused_widget_before_widthdraw = None + # set CustomTkinter titlebar icon (Windows only) if sys.platform.startswith("win"): self.after(200, self._windows_set_titlebar_icon) @@ -238,6 +241,7 @@ class CTkToplevel(tkinter.Toplevel, CTkAppearanceModeBaseClass, CTkScalingBaseCl if sys.platform.startswith("win") and not self._deactivate_windows_window_header_manipulation: self._state_before_windows_set_titlebar_color = self.state() + self.focused_widget_before_widthdraw = self.focus_get() super().withdraw() # hide window so that it can be redrawn after the titlebar change so that the color change is visible super().update() @@ -268,6 +272,10 @@ class CTkToplevel(tkinter.Toplevel, CTkAppearanceModeBaseClass, CTkScalingBaseCl self._windows_set_titlebar_color_called = True self.after(5, self._revert_withdraw_after_windows_set_titlebar_color) + if self.focused_widget_before_widthdraw is not None: + self.after(10, self.focused_widget_before_widthdraw.focus) + self.focused_widget_before_widthdraw = None + def _revert_withdraw_after_windows_set_titlebar_color(self): """ if in a short time (5ms) after """ if self._windows_set_titlebar_color_called: diff --git a/customtkinter/windows/widgets/__init__.py b/customtkinter/windows/widgets/__init__.py index 2e21484..a75c63d 100644 --- a/customtkinter/windows/widgets/__init__.py +++ b/customtkinter/windows/widgets/__init__.py @@ -13,3 +13,4 @@ from .ctk_slider import CTkSlider from .ctk_switch import CTkSwitch from .ctk_tabview import CTkTabview from .ctk_textbox import CTkTextbox +from .ctk_scrollable_frame import CTkScrollableFrame diff --git a/customtkinter/windows/widgets/__pycache__/__init__.cpython-310.pyc b/customtkinter/windows/widgets/__pycache__/__init__.cpython-310.pyc index 73f0ec8..cacbdd6 100644 Binary files a/customtkinter/windows/widgets/__pycache__/__init__.cpython-310.pyc and b/customtkinter/windows/widgets/__pycache__/__init__.cpython-310.pyc differ diff --git a/customtkinter/windows/widgets/__pycache__/__init__.cpython-37.pyc b/customtkinter/windows/widgets/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000..0db5e33 Binary files /dev/null and b/customtkinter/windows/widgets/__pycache__/__init__.cpython-37.pyc differ diff --git a/customtkinter/windows/widgets/__pycache__/ctk_button.cpython-310.pyc b/customtkinter/windows/widgets/__pycache__/ctk_button.cpython-310.pyc index 86dca20..7e6c1a3 100644 Binary files a/customtkinter/windows/widgets/__pycache__/ctk_button.cpython-310.pyc and b/customtkinter/windows/widgets/__pycache__/ctk_button.cpython-310.pyc differ diff --git a/customtkinter/windows/widgets/__pycache__/ctk_button.cpython-37.pyc b/customtkinter/windows/widgets/__pycache__/ctk_button.cpython-37.pyc new file mode 100644 index 0000000..4432e0a Binary files /dev/null and b/customtkinter/windows/widgets/__pycache__/ctk_button.cpython-37.pyc differ diff --git a/customtkinter/windows/widgets/__pycache__/ctk_checkbox.cpython-310.pyc b/customtkinter/windows/widgets/__pycache__/ctk_checkbox.cpython-310.pyc index 32780b3..277de97 100644 Binary files a/customtkinter/windows/widgets/__pycache__/ctk_checkbox.cpython-310.pyc and b/customtkinter/windows/widgets/__pycache__/ctk_checkbox.cpython-310.pyc differ diff --git a/customtkinter/windows/widgets/__pycache__/ctk_combobox.cpython-310.pyc b/customtkinter/windows/widgets/__pycache__/ctk_combobox.cpython-310.pyc index 69de504..a6702d2 100644 Binary files a/customtkinter/windows/widgets/__pycache__/ctk_combobox.cpython-310.pyc and b/customtkinter/windows/widgets/__pycache__/ctk_combobox.cpython-310.pyc differ diff --git a/customtkinter/windows/widgets/__pycache__/ctk_entry.cpython-310.pyc b/customtkinter/windows/widgets/__pycache__/ctk_entry.cpython-310.pyc index 9d46fcc..6beeab1 100644 Binary files a/customtkinter/windows/widgets/__pycache__/ctk_entry.cpython-310.pyc and b/customtkinter/windows/widgets/__pycache__/ctk_entry.cpython-310.pyc differ diff --git a/customtkinter/windows/widgets/__pycache__/ctk_frame.cpython-310.pyc b/customtkinter/windows/widgets/__pycache__/ctk_frame.cpython-310.pyc index 7cd10e9..14f3fea 100644 Binary files a/customtkinter/windows/widgets/__pycache__/ctk_frame.cpython-310.pyc and b/customtkinter/windows/widgets/__pycache__/ctk_frame.cpython-310.pyc differ diff --git a/customtkinter/windows/widgets/__pycache__/ctk_label.cpython-310.pyc b/customtkinter/windows/widgets/__pycache__/ctk_label.cpython-310.pyc index 2bb792f..843953f 100644 Binary files a/customtkinter/windows/widgets/__pycache__/ctk_label.cpython-310.pyc and b/customtkinter/windows/widgets/__pycache__/ctk_label.cpython-310.pyc differ diff --git a/customtkinter/windows/widgets/__pycache__/ctk_optionmenu.cpython-310.pyc b/customtkinter/windows/widgets/__pycache__/ctk_optionmenu.cpython-310.pyc index da0d6f0..2ac7c97 100644 Binary files a/customtkinter/windows/widgets/__pycache__/ctk_optionmenu.cpython-310.pyc and b/customtkinter/windows/widgets/__pycache__/ctk_optionmenu.cpython-310.pyc differ diff --git a/customtkinter/windows/widgets/__pycache__/ctk_progressbar.cpython-310.pyc b/customtkinter/windows/widgets/__pycache__/ctk_progressbar.cpython-310.pyc index 4c4d4ec..917483b 100644 Binary files a/customtkinter/windows/widgets/__pycache__/ctk_progressbar.cpython-310.pyc and b/customtkinter/windows/widgets/__pycache__/ctk_progressbar.cpython-310.pyc differ diff --git a/customtkinter/windows/widgets/__pycache__/ctk_radiobutton.cpython-310.pyc b/customtkinter/windows/widgets/__pycache__/ctk_radiobutton.cpython-310.pyc index 8923c8a..079684d 100644 Binary files a/customtkinter/windows/widgets/__pycache__/ctk_radiobutton.cpython-310.pyc and b/customtkinter/windows/widgets/__pycache__/ctk_radiobutton.cpython-310.pyc differ diff --git a/customtkinter/windows/widgets/__pycache__/ctk_scrollable_frame.cpython-310.pyc b/customtkinter/windows/widgets/__pycache__/ctk_scrollable_frame.cpython-310.pyc new file mode 100644 index 0000000..bff19af Binary files /dev/null and b/customtkinter/windows/widgets/__pycache__/ctk_scrollable_frame.cpython-310.pyc differ diff --git a/customtkinter/windows/widgets/__pycache__/ctk_scrollbar.cpython-310.pyc b/customtkinter/windows/widgets/__pycache__/ctk_scrollbar.cpython-310.pyc index 924b2c9..e9a5241 100644 Binary files a/customtkinter/windows/widgets/__pycache__/ctk_scrollbar.cpython-310.pyc and b/customtkinter/windows/widgets/__pycache__/ctk_scrollbar.cpython-310.pyc differ diff --git a/customtkinter/windows/widgets/__pycache__/ctk_segmented_button.cpython-310.pyc b/customtkinter/windows/widgets/__pycache__/ctk_segmented_button.cpython-310.pyc index 26db9d4..84ad5ad 100644 Binary files a/customtkinter/windows/widgets/__pycache__/ctk_segmented_button.cpython-310.pyc and b/customtkinter/windows/widgets/__pycache__/ctk_segmented_button.cpython-310.pyc differ diff --git a/customtkinter/windows/widgets/__pycache__/ctk_slider.cpython-310.pyc b/customtkinter/windows/widgets/__pycache__/ctk_slider.cpython-310.pyc index d177816..ed3416e 100644 Binary files a/customtkinter/windows/widgets/__pycache__/ctk_slider.cpython-310.pyc and b/customtkinter/windows/widgets/__pycache__/ctk_slider.cpython-310.pyc differ diff --git a/customtkinter/windows/widgets/__pycache__/ctk_switch.cpython-310.pyc b/customtkinter/windows/widgets/__pycache__/ctk_switch.cpython-310.pyc index 1504b0a..d16c729 100644 Binary files a/customtkinter/windows/widgets/__pycache__/ctk_switch.cpython-310.pyc and b/customtkinter/windows/widgets/__pycache__/ctk_switch.cpython-310.pyc differ diff --git a/customtkinter/windows/widgets/__pycache__/ctk_tabview.cpython-310.pyc b/customtkinter/windows/widgets/__pycache__/ctk_tabview.cpython-310.pyc index a4101ab..d63e815 100644 Binary files a/customtkinter/windows/widgets/__pycache__/ctk_tabview.cpython-310.pyc and b/customtkinter/windows/widgets/__pycache__/ctk_tabview.cpython-310.pyc differ diff --git a/customtkinter/windows/widgets/__pycache__/ctk_textbox.cpython-310.pyc b/customtkinter/windows/widgets/__pycache__/ctk_textbox.cpython-310.pyc index 2ddb1dc..59fdb22 100644 Binary files a/customtkinter/windows/widgets/__pycache__/ctk_textbox.cpython-310.pyc and b/customtkinter/windows/widgets/__pycache__/ctk_textbox.cpython-310.pyc differ diff --git a/customtkinter/windows/widgets/appearance_mode/__pycache__/__init__.cpython-310.pyc b/customtkinter/windows/widgets/appearance_mode/__pycache__/__init__.cpython-310.pyc index 0a824e1..fada98c 100644 Binary files a/customtkinter/windows/widgets/appearance_mode/__pycache__/__init__.cpython-310.pyc and b/customtkinter/windows/widgets/appearance_mode/__pycache__/__init__.cpython-310.pyc differ diff --git a/customtkinter/windows/widgets/appearance_mode/__pycache__/appearance_mode_base_class.cpython-310.pyc b/customtkinter/windows/widgets/appearance_mode/__pycache__/appearance_mode_base_class.cpython-310.pyc index bc10541..669edf1 100644 Binary files a/customtkinter/windows/widgets/appearance_mode/__pycache__/appearance_mode_base_class.cpython-310.pyc and b/customtkinter/windows/widgets/appearance_mode/__pycache__/appearance_mode_base_class.cpython-310.pyc differ diff --git a/customtkinter/windows/widgets/appearance_mode/__pycache__/appearance_mode_tracker.cpython-310.pyc b/customtkinter/windows/widgets/appearance_mode/__pycache__/appearance_mode_tracker.cpython-310.pyc index 6508b64..c8b52a0 100644 Binary files a/customtkinter/windows/widgets/appearance_mode/__pycache__/appearance_mode_tracker.cpython-310.pyc and b/customtkinter/windows/widgets/appearance_mode/__pycache__/appearance_mode_tracker.cpython-310.pyc differ diff --git a/customtkinter/windows/widgets/appearance_mode/appearance_mode_base_class.py b/customtkinter/windows/widgets/appearance_mode/appearance_mode_base_class.py index 0d19147..b7f757a 100644 --- a/customtkinter/windows/widgets/appearance_mode/appearance_mode_base_class.py +++ b/customtkinter/windows/widgets/appearance_mode/appearance_mode_base_class.py @@ -9,7 +9,7 @@ class CTkAppearanceModeBaseClass: - destroy() must be called when sub-class is destroyed - _set_appearance_mode() abstractmethod, gets called when appearance mode changes, must be overridden - - _apply_appearance_mode() + - _apply_appearance_mode() to convert tuple color """ def __init__(self): diff --git a/customtkinter/windows/widgets/core_rendering/__pycache__/__init__.cpython-310.pyc b/customtkinter/windows/widgets/core_rendering/__pycache__/__init__.cpython-310.pyc index 1123f3c..612a48d 100644 Binary files a/customtkinter/windows/widgets/core_rendering/__pycache__/__init__.cpython-310.pyc and b/customtkinter/windows/widgets/core_rendering/__pycache__/__init__.cpython-310.pyc differ diff --git a/customtkinter/windows/widgets/core_rendering/__pycache__/__init__.cpython-37.pyc b/customtkinter/windows/widgets/core_rendering/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000..97f8cf1 Binary files /dev/null and b/customtkinter/windows/widgets/core_rendering/__pycache__/__init__.cpython-37.pyc differ diff --git a/customtkinter/windows/widgets/core_rendering/__pycache__/ctk_canvas.cpython-310.pyc b/customtkinter/windows/widgets/core_rendering/__pycache__/ctk_canvas.cpython-310.pyc index d8926ce..7d6f55b 100644 Binary files a/customtkinter/windows/widgets/core_rendering/__pycache__/ctk_canvas.cpython-310.pyc and b/customtkinter/windows/widgets/core_rendering/__pycache__/ctk_canvas.cpython-310.pyc differ diff --git a/customtkinter/windows/widgets/core_rendering/__pycache__/ctk_canvas.cpython-37.pyc b/customtkinter/windows/widgets/core_rendering/__pycache__/ctk_canvas.cpython-37.pyc new file mode 100644 index 0000000..b119a76 Binary files /dev/null and b/customtkinter/windows/widgets/core_rendering/__pycache__/ctk_canvas.cpython-37.pyc differ diff --git a/customtkinter/windows/widgets/core_rendering/__pycache__/draw_engine.cpython-310.pyc b/customtkinter/windows/widgets/core_rendering/__pycache__/draw_engine.cpython-310.pyc index ac10c84..7528bc8 100644 Binary files a/customtkinter/windows/widgets/core_rendering/__pycache__/draw_engine.cpython-310.pyc and b/customtkinter/windows/widgets/core_rendering/__pycache__/draw_engine.cpython-310.pyc differ diff --git a/customtkinter/windows/widgets/core_rendering/__pycache__/draw_engine.cpython-37.pyc b/customtkinter/windows/widgets/core_rendering/__pycache__/draw_engine.cpython-37.pyc new file mode 100644 index 0000000..8aa258b Binary files /dev/null and b/customtkinter/windows/widgets/core_rendering/__pycache__/draw_engine.cpython-37.pyc differ diff --git a/customtkinter/windows/widgets/core_widget_classes/__pycache__/__init__.cpython-310.pyc b/customtkinter/windows/widgets/core_widget_classes/__pycache__/__init__.cpython-310.pyc index 3550f89..7acb7bb 100644 Binary files a/customtkinter/windows/widgets/core_widget_classes/__pycache__/__init__.cpython-310.pyc and b/customtkinter/windows/widgets/core_widget_classes/__pycache__/__init__.cpython-310.pyc differ diff --git a/customtkinter/windows/widgets/core_widget_classes/__pycache__/__init__.cpython-37.pyc b/customtkinter/windows/widgets/core_widget_classes/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000..6242076 Binary files /dev/null and b/customtkinter/windows/widgets/core_widget_classes/__pycache__/__init__.cpython-37.pyc differ diff --git a/customtkinter/windows/widgets/core_widget_classes/__pycache__/ctk_base_class.cpython-310.pyc b/customtkinter/windows/widgets/core_widget_classes/__pycache__/ctk_base_class.cpython-310.pyc index a056c52..b08ee85 100644 Binary files a/customtkinter/windows/widgets/core_widget_classes/__pycache__/ctk_base_class.cpython-310.pyc and b/customtkinter/windows/widgets/core_widget_classes/__pycache__/ctk_base_class.cpython-310.pyc differ diff --git a/customtkinter/windows/widgets/core_widget_classes/__pycache__/dropdown_menu.cpython-310.pyc b/customtkinter/windows/widgets/core_widget_classes/__pycache__/dropdown_menu.cpython-310.pyc index c3ad3ea..225be27 100644 Binary files a/customtkinter/windows/widgets/core_widget_classes/__pycache__/dropdown_menu.cpython-310.pyc and b/customtkinter/windows/widgets/core_widget_classes/__pycache__/dropdown_menu.cpython-310.pyc differ diff --git a/customtkinter/windows/widgets/core_widget_classes/__pycache__/dropdown_menu.cpython-37.pyc b/customtkinter/windows/widgets/core_widget_classes/__pycache__/dropdown_menu.cpython-37.pyc new file mode 100644 index 0000000..c10048d Binary files /dev/null and b/customtkinter/windows/widgets/core_widget_classes/__pycache__/dropdown_menu.cpython-37.pyc differ diff --git a/customtkinter/windows/widgets/core_widget_classes/ctk_base_class.py b/customtkinter/windows/widgets/core_widget_classes/ctk_base_class.py index a75ab01..610f46a 100644 --- a/customtkinter/windows/widgets/core_widget_classes/ctk_base_class.py +++ b/customtkinter/windows/widgets/core_widget_classes/ctk_base_class.py @@ -9,9 +9,6 @@ try: except ImportError: from typing_extensions import TypedDict -# removed due to circular import -# from ...ctk_tk import CTk -# from ...ctk_toplevel import CTkToplevel from .... import windows # import windows for isinstance checks from ..theme import ThemeManager @@ -74,7 +71,7 @@ class CTkBaseClass(tkinter.Frame, CTkAppearanceModeBaseClass, CTkScalingBaseClas super().bind('', self._update_dimensions_event) # overwrite configure methods of master when master is tkinter widget, so that bg changes get applied on child CTk widget as well - if isinstance(self.master, (tkinter.Tk, tkinter.Toplevel, tkinter.Frame, tkinter.LabelFrame, ttk.Frame, ttk.LabelFrame, ttk.Notebook)) and not isinstance(self.master, CTkBaseClass): + if isinstance(self.master, (tkinter.Tk, tkinter.Toplevel, tkinter.Frame, tkinter.LabelFrame, ttk.Frame, ttk.LabelFrame, ttk.Notebook)) and not isinstance(self.master, (CTkBaseClass, CTkAppearanceModeBaseClass)): master_old_configure = self.master.config def new_configure(*args, **kwargs): @@ -179,8 +176,7 @@ class CTkBaseClass(tkinter.Frame, CTkAppearanceModeBaseClass, CTkScalingBaseClas elif isinstance(image, CTkImage): return image else: - warnings.warn(f"{type(self).__name__} Warning: Given image is not CTkImage but {type(image)}. " + - f"Image can not be scaled on HighDPI displays, use CTkImage instead.\n") + warnings.warn(f"{type(self).__name__} Warning: Given image is not CTkImage but {type(image)}. Image can not be scaled on HighDPI displays, use CTkImage instead.\n") return image def _update_dimensions_event(self, event): @@ -197,12 +193,15 @@ class CTkBaseClass(tkinter.Frame, CTkAppearanceModeBaseClass, CTkScalingBaseClas if master_widget is None: master_widget = self.master - if isinstance(master_widget, (windows.widgets.core_widget_classes.CTkBaseClass, windows.CTk, windows.CTkToplevel)): + if isinstance(master_widget, (windows.widgets.core_widget_classes.CTkBaseClass, windows.CTk, windows.CTkToplevel, windows.widgets.ctk_scrollable_frame.CTkScrollableFrame)): if master_widget.cget("fg_color") is not None and master_widget.cget("fg_color") != "transparent": return master_widget.cget("fg_color") + elif isinstance(master_widget, windows.widgets.ctk_scrollable_frame.CTkScrollableFrame): + return self._detect_color_of_master(master_widget.master.master.master) + # if fg_color of master is None, try to retrieve fg_color from master of master - elif hasattr(master_widget.master, "master"): + elif hasattr(master_widget, "master"): return self._detect_color_of_master(master_widget.master) elif isinstance(master_widget, (ttk.Frame, ttk.LabelFrame, ttk.Notebook, ttk.Label)): # master is ttk widget @@ -269,6 +268,8 @@ class CTkBaseClass(tkinter.Frame, CTkAppearanceModeBaseClass, CTkScalingBaseClas relheight=amount - height of this widget between 0.0 and 1.0 relative to height of master (1.0 is the same height as the master) bordermode="inside" or "outside" - whether to take border width of master widget into account """ + if "width" in kwargs or "height" in kwargs: + raise ValueError("'width' and 'height' arguments must be passed to the constructor of the widget, not the place method") self._last_geometry_manager_call = {"function": super().place, "kwargs": kwargs} return super().place(**self._apply_argument_scaling(kwargs)) diff --git a/customtkinter/windows/widgets/ctk_button.py b/customtkinter/windows/widgets/ctk_button.py index 45ed025..d79a944 100644 --- a/customtkinter/windows/widgets/ctk_button.py +++ b/customtkinter/windows/widgets/ctk_button.py @@ -40,7 +40,7 @@ class CTkButton(CTkBaseClass): text: str = "CTkButton", font: Optional[Union[tuple, CTkFont]] = None, textvariable: Union[tkinter.Variable, None] = None, - image: Union[CTkImage, None] = None, + image: Union[CTkImage, "ImageTk.PhotoImage", None] = None, state: str = "normal", hover: bool = True, command: Union[Callable[[], None], None] = None, @@ -169,8 +169,11 @@ class CTkButton(CTkBaseClass): def _update_image(self): if self._image_label is not None: - self._image_label.configure(image=self._image.create_scaled_photo_image(self._get_widget_scaling(), - self._get_appearance_mode())) + if isinstance(self._image, CTkImage): + self._image_label.configure(image=self._image.create_scaled_photo_image(self._get_widget_scaling(), + self._get_appearance_mode())) + elif self._image is not None: + self._image_label.configure(image=self._image) def destroy(self): if isinstance(self._font, CTkFont): @@ -425,6 +428,7 @@ class CTkButton(CTkBaseClass): if "command" in kwargs: self._command = kwargs.pop("command") + self._set_cursor() if "compound" in kwargs: self._compound = kwargs.pop("compound") diff --git a/customtkinter/windows/widgets/ctk_entry.py b/customtkinter/windows/widgets/ctk_entry.py index 6a2560b..db54386 100644 --- a/customtkinter/windows/widgets/ctk_entry.py +++ b/customtkinter/windows/widgets/ctk_entry.py @@ -133,7 +133,7 @@ class CTkEntry(CTkBaseClass): self._canvas.configure(width=self._apply_widget_scaling(self._desired_width), height=self._apply_widget_scaling(self._desired_height)) - self._draw() + self._draw(no_color_updates=True) def _update_font(self): """ pass font to tkinter widgets with applied font scaling and update grid with workaround """ @@ -153,14 +153,14 @@ class CTkEntry(CTkBaseClass): def _draw(self, no_color_updates=False): super()._draw(no_color_updates) - self._canvas.configure(bg=self._apply_appearance_mode(self._bg_color)) - requires_recoloring = self._draw_engine.draw_rounded_rect_with_border(self._apply_widget_scaling(self._current_width), self._apply_widget_scaling(self._current_height), self._apply_widget_scaling(self._corner_radius), self._apply_widget_scaling(self._border_width)) if requires_recoloring or no_color_updates is False: + self._canvas.configure(bg=self._apply_appearance_mode(self._bg_color)) + if self._apply_appearance_mode(self._fg_color) == "transparent": self._canvas.itemconfig("inner_parts", fill=self._apply_appearance_mode(self._bg_color), @@ -342,13 +342,13 @@ class CTkEntry(CTkBaseClass): return self._entry.get() def focus(self): - return self._entry.focus() + self._entry.focus() def focus_set(self): - return self._entry.focus_set() + self._entry.focus_set() def focus_force(self): - return self._entry.focus_force() + self._entry.focus_force() def index(self, index): return self._entry.index(index) diff --git a/customtkinter/windows/widgets/ctk_frame.py b/customtkinter/windows/widgets/ctk_frame.py index fe9e226..67bf161 100644 --- a/customtkinter/windows/widgets/ctk_frame.py +++ b/customtkinter/windows/widgets/ctk_frame.py @@ -24,8 +24,8 @@ class CTkFrame(CTkBaseClass): bg_color: Union[str, Tuple[str, str]] = "transparent", fg_color: Optional[Union[str, Tuple[str, str]]] = None, border_color: Optional[Union[str, Tuple[str, str]]] = None, - background_corner_colors: Union[Tuple[Union[str, Tuple[str, str]]], None] = None, + background_corner_colors: Union[Tuple[Union[str, Tuple[str, str]]], None] = None, overwrite_preferred_drawing_method: Union[str, None] = None, **kwargs): diff --git a/customtkinter/windows/widgets/ctk_scrollable_frame.py b/customtkinter/windows/widgets/ctk_scrollable_frame.py new file mode 100644 index 0000000..685deb2 --- /dev/null +++ b/customtkinter/windows/widgets/ctk_scrollable_frame.py @@ -0,0 +1,316 @@ +from typing import Union, Tuple, Optional +try: + from typing import Literal +except ImportError: + from typing_extensions import Literal +import tkinter +import sys + +from .ctk_frame import CTkFrame +from .ctk_scrollbar import CTkScrollbar +from .appearance_mode import CTkAppearanceModeBaseClass +from .scaling import CTkScalingBaseClass +from .core_widget_classes import CTkBaseClass +from .ctk_label import CTkLabel +from .font import CTkFont +from .theme import ThemeManager + + +class CTkScrollableFrame(tkinter.Frame, CTkAppearanceModeBaseClass, CTkScalingBaseClass): + def __init__(self, + master: any, + width: int = 200, + height: int = 200, + corner_radius: Optional[Union[int, str]] = None, + border_width: Optional[Union[int, str]] = None, + + bg_color: Union[str, Tuple[str, str]] = "transparent", + fg_color: Optional[Union[str, Tuple[str, str]]] = None, + border_color: Optional[Union[str, Tuple[str, str]]] = None, + scrollbar_fg_color: Optional[Union[str, Tuple[str, str]]] = None, + scrollbar_button_color: Optional[Union[str, Tuple[str, str]]] = None, + scrollbar_button_hover_color: Optional[Union[str, Tuple[str, str]]] = None, + label_fg_color: Optional[Union[str, Tuple[str, str]]] = None, + label_text_color: Optional[Union[str, Tuple[str, str]]] = None, + + label_text: str = "", + label_font: Optional[Union[tuple, CTkFont]] = None, + label_anchor: str = "center", + orientation: Literal["vertical", "horizontal"] = "vertical"): + + self._orientation = orientation + + # dimensions independent of scaling + self._desired_width = width # _desired_width and _desired_height, represent desired size set by width and height + self._desired_height = height + + self._parent_frame = CTkFrame(master=master, width=0, height=0, corner_radius=corner_radius, + border_width=border_width, bg_color=bg_color, fg_color=fg_color, border_color=border_color) + self._parent_canvas = tkinter.Canvas(master=self._parent_frame, highlightthickness=0) + self._set_scroll_increments() + + if self._orientation == "horizontal": + self._scrollbar = CTkScrollbar(master=self._parent_frame, orientation="horizontal", command=self._parent_canvas.xview, + fg_color=scrollbar_fg_color, button_color=scrollbar_button_color, button_hover_color=scrollbar_button_hover_color) + self._parent_canvas.configure(xscrollcommand=self._scrollbar.set) + elif self._orientation == "vertical": + self._scrollbar = CTkScrollbar(master=self._parent_frame, orientation="vertical", command=self._parent_canvas.yview, + fg_color=scrollbar_fg_color, button_color=scrollbar_button_color, button_hover_color=scrollbar_button_hover_color) + self._parent_canvas.configure(yscrollcommand=self._scrollbar.set) + + self._label_text = label_text + self._label = CTkLabel(self._parent_frame, text=label_text, anchor=label_anchor, font=label_font, + corner_radius=self._parent_frame.cget("corner_radius"), text_color=label_text_color, + fg_color=ThemeManager.theme["CTkScrollableFrame"]["label_fg_color"] if label_fg_color is None else label_fg_color) + + tkinter.Frame.__init__(self, master=self._parent_canvas, highlightthickness=0) + CTkAppearanceModeBaseClass.__init__(self) + CTkScalingBaseClass.__init__(self, scaling_type="widget") + + self._create_grid() + + self._parent_canvas.configure(width=self._apply_widget_scaling(self._desired_width), + height=self._apply_widget_scaling(self._desired_height)) + + self.bind("", lambda e: self._parent_canvas.configure(scrollregion=self._parent_canvas.bbox("all"))) + self._parent_canvas.bind("", self._fit_frame_dimensions_to_canvas) + self.bind_all("", self._mouse_wheel_all, add="+") + self.bind_all("", self._keyboard_shift_press_all, add="+") + self.bind_all("", self._keyboard_shift_press_all, add="+") + self.bind_all("", self._keyboard_shift_release_all, add="+") + self.bind_all("", self._keyboard_shift_release_all, add="+") + self._create_window_id = self._parent_canvas.create_window(0, 0, window=self, anchor="nw") + + if self._parent_frame.cget("fg_color") == "transparent": + tkinter.Frame.configure(self, bg=self._apply_appearance_mode(self._parent_frame.cget("bg_color"))) + self._parent_canvas.configure(bg=self._apply_appearance_mode(self._parent_frame.cget("bg_color"))) + else: + tkinter.Frame.configure(self, bg=self._apply_appearance_mode(self._parent_frame.cget("fg_color"))) + self._parent_canvas.configure(bg=self._apply_appearance_mode(self._parent_frame.cget("fg_color"))) + + self._shift_pressed = False + + def destroy(self): + tkinter.Frame.destroy(self) + CTkAppearanceModeBaseClass.destroy(self) + CTkScalingBaseClass.destroy(self) + + def _create_grid(self): + border_spacing = self._apply_widget_scaling(self._parent_frame.cget("corner_radius") + self._parent_frame.cget("border_width")) + + if self._orientation == "horizontal": + self._parent_frame.grid_columnconfigure(0, weight=1) + self._parent_frame.grid_rowconfigure(1, weight=1) + self._parent_canvas.grid(row=1, column=0, sticky="nsew", padx=border_spacing, pady=(border_spacing, 0)) + self._scrollbar.grid(row=2, column=0, sticky="nsew", padx=border_spacing) + + if self._label_text is not None and self._label_text != "": + self._label.grid(row=0, column=0, sticky="ew", padx=border_spacing, pady=border_spacing) + else: + self._label.grid_forget() + + elif self._orientation == "vertical": + self._parent_frame.grid_columnconfigure(0, weight=1) + self._parent_frame.grid_rowconfigure(1, weight=1) + self._parent_canvas.grid(row=1, column=0, sticky="nsew", padx=(border_spacing, 0), pady=border_spacing) + self._scrollbar.grid(row=1, column=1, sticky="nsew", pady=border_spacing) + + if self._label_text is not None and self._label_text != "": + self._label.grid(row=0, column=0, columnspan=2, sticky="ew", padx=border_spacing, pady=border_spacing) + else: + self._label.grid_forget() + + def _set_appearance_mode(self, mode_string): + super()._set_appearance_mode(mode_string) + + if self._parent_frame.cget("fg_color") == "transparent": + tkinter.Frame.configure(self, bg=self._apply_appearance_mode(self._parent_frame.cget("bg_color"))) + self._parent_canvas.configure(bg=self._apply_appearance_mode(self._parent_frame.cget("bg_color"))) + else: + tkinter.Frame.configure(self, bg=self._apply_appearance_mode(self._parent_frame.cget("fg_color"))) + self._parent_canvas.configure(bg=self._apply_appearance_mode(self._parent_frame.cget("fg_color"))) + + def _set_scaling(self, new_widget_scaling, new_window_scaling): + super()._set_scaling(new_widget_scaling, new_window_scaling) + + self._parent_canvas.configure(width=self._apply_widget_scaling(self._desired_width), + height=self._apply_widget_scaling(self._desired_height)) + + def _set_dimensions(self, width=None, height=None): + if width is not None: + self._desired_width = width + if height is not None: + self._desired_height = height + + self._parent_canvas.configure(width=self._apply_widget_scaling(self._desired_width), + height=self._apply_widget_scaling(self._desired_height)) + + def configure(self, **kwargs): + if "width" in kwargs: + self._set_dimensions(width=kwargs.pop("width")) + + if "height" in kwargs: + self._set_dimensions(height=kwargs.pop("height")) + + if "corner_radius" in kwargs: + new_corner_radius = kwargs.pop("corner_radius") + self._parent_frame.configure(corner_radius=new_corner_radius) + if self._label is not None: + self._label.configure(corner_radius=new_corner_radius) + self._create_grid() + + if "border_width" in kwargs: + self._parent_frame.configure(border_width=kwargs.pop("border_width")) + self._create_grid() + + if "fg_color" in kwargs: + self._parent_frame.configure(fg_color=kwargs.pop("fg_color")) + + if self._parent_frame.cget("fg_color") == "transparent": + tkinter.Frame.configure(self, bg=self._apply_appearance_mode(self._parent_frame.cget("bg_color"))) + self._parent_canvas.configure(bg=self._apply_appearance_mode(self._parent_frame.cget("bg_color"))) + else: + tkinter.Frame.configure(self, bg=self._apply_appearance_mode(self._parent_frame.cget("fg_color"))) + self._parent_canvas.configure(bg=self._apply_appearance_mode(self._parent_frame.cget("fg_color"))) + + for child in self.winfo_children(): + if isinstance(child, CTkBaseClass): + child.configure(bg_color=self._parent_frame.cget("fg_color")) + + if "scrollbar_fg_color" in kwargs: + self._scrollbar.configure(fg_color=kwargs.pop("scrollbar_fg_color")) + + if "scrollbar_button_color" in kwargs: + self._scrollbar.configure(fg_color=kwargs.pop("scrollbar_button_color")) + + if "scrollbar_button_hover_color" in kwargs: + self._scrollbar.configure(fg_color=kwargs.pop("scrollbar_button_hover_color")) + + if "label_text" in kwargs: + self._label_text = kwargs.pop("label_text") + self._label.configure(text=self._label_text) + self._create_grid() + + if "label_font" in kwargs: + self._label.configure(font=kwargs.pop("label_font")) + + if "label_text_color" in kwargs: + self._label.configure(text_color=kwargs.pop("label_text_color")) + + if "label_fg_color" in kwargs: + self._label.configure(fg_color=kwargs.pop("label_fg_color")) + + if "label_anchor" in kwargs: + self._label.configure(anchor=kwargs.pop("label_anchor")) + + self._parent_frame.configure(**kwargs) + + def cget(self, attribute_name: str): + if attribute_name == "width": + return self._desired_width + elif attribute_name == "height": + return self._desired_height + + elif attribute_name == "label_text": + return self._label_text + elif attribute_name == "label_font": + return self._label.cget("font") + elif attribute_name == "label_text_color": + return self._label.cget("_text_color") + elif attribute_name == "label_fg_color": + return self._label.cget("fg_color") + elif attribute_name == "label_anchor": + return self._label.cget("anchor") + + elif attribute_name.startswith("scrollbar_fg_color"): + return self._scrollbar.cget("fg_color") + elif attribute_name.startswith("scrollbar_button_color"): + return self._scrollbar.cget("button_color") + elif attribute_name.startswith("scrollbar_button_hover_color"): + return self._scrollbar.cget("button_hover_color") + + else: + return self._parent_frame.cget(attribute_name) + + def _fit_frame_dimensions_to_canvas(self, event): + if self._orientation == "horizontal": + self._parent_canvas.itemconfigure(self._create_window_id, height=self._parent_canvas.winfo_height()) + elif self._orientation == "vertical": + self._parent_canvas.itemconfigure(self._create_window_id, width=self._parent_canvas.winfo_width()) + + def _set_scroll_increments(self): + if sys.platform.startswith("win"): + self._parent_canvas.configure(xscrollincrement=1, yscrollincrement=1) + elif sys.platform == "darwin": + self._parent_canvas.configure(xscrollincrement=4, yscrollincrement=8) + + def _mouse_wheel_all(self, event): + if self.check_if_master_is_canvas(event.widget): + if sys.platform.startswith("win"): + if self._shift_pressed: + if self._parent_canvas.xview() != (0.0, 1.0): + self._parent_canvas.xview("scroll", -int(event.delta / 6), "units") + else: + if self._parent_canvas.yview() != (0.0, 1.0): + self._parent_canvas.yview("scroll", -int(event.delta / 6), "units") + elif sys.platform == "darwin": + if self._shift_pressed: + if self._parent_canvas.xview() != (0.0, 1.0): + self._parent_canvas.xview("scroll", -event.delta, "units") + else: + if self._parent_canvas.yview() != (0.0, 1.0): + self._parent_canvas.yview("scroll", -event.delta, "units") + else: + if self._shift_pressed: + if self._parent_canvas.xview() != (0.0, 1.0): + self._parent_canvas.xview("scroll", -event.delta, "units") + else: + if self._parent_canvas.yview() != (0.0, 1.0): + self._parent_canvas.yview("scroll", -event.delta, "units") + + def _keyboard_shift_press_all(self, event): + self._shift_pressed = True + + def _keyboard_shift_release_all(self, event): + self._shift_pressed = False + + def check_if_master_is_canvas(self, widget): + if widget == self._parent_canvas: + return True + elif widget.master is not None: + return self.check_if_master_is_canvas(widget.master) + else: + return False + + def pack(self, **kwargs): + self._parent_frame.pack(**kwargs) + + def place(self, **kwargs): + self._parent_frame.place(**kwargs) + + def grid(self, **kwargs): + self._parent_frame.grid(**kwargs) + + def pack_forget(self): + self._parent_frame.pack_forget() + + def place_forget(self, **kwargs): + self._parent_frame.place_forget() + + def grid_forget(self, **kwargs): + self._parent_frame.grid_forget() + + def grid_remove(self, **kwargs): + self._parent_frame.grid_remove() + + def grid_propagate(self, **kwargs): + self._parent_frame.grid_propagate() + + def grid_info(self, **kwargs): + return self._parent_frame.grid_info() + + def lift(self, aboveThis=None): + self._parent_frame.lift(aboveThis) + + def lower(self, belowThis=None): + self._parent_frame.lower(belowThis) diff --git a/customtkinter/windows/widgets/font/__pycache__/__init__.cpython-310.pyc b/customtkinter/windows/widgets/font/__pycache__/__init__.cpython-310.pyc index 4d83821..b1801a0 100644 Binary files a/customtkinter/windows/widgets/font/__pycache__/__init__.cpython-310.pyc and b/customtkinter/windows/widgets/font/__pycache__/__init__.cpython-310.pyc differ diff --git a/customtkinter/windows/widgets/font/__pycache__/__init__.cpython-37.pyc b/customtkinter/windows/widgets/font/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000..81ca1df Binary files /dev/null and b/customtkinter/windows/widgets/font/__pycache__/__init__.cpython-37.pyc differ diff --git a/customtkinter/windows/widgets/font/__pycache__/ctk_font.cpython-310.pyc b/customtkinter/windows/widgets/font/__pycache__/ctk_font.cpython-310.pyc index a87499a..4ac271a 100644 Binary files a/customtkinter/windows/widgets/font/__pycache__/ctk_font.cpython-310.pyc and b/customtkinter/windows/widgets/font/__pycache__/ctk_font.cpython-310.pyc differ diff --git a/customtkinter/windows/widgets/font/__pycache__/ctk_font.cpython-37.pyc b/customtkinter/windows/widgets/font/__pycache__/ctk_font.cpython-37.pyc new file mode 100644 index 0000000..181e8e3 Binary files /dev/null and b/customtkinter/windows/widgets/font/__pycache__/ctk_font.cpython-37.pyc differ diff --git a/customtkinter/windows/widgets/font/__pycache__/font_manager.cpython-310.pyc b/customtkinter/windows/widgets/font/__pycache__/font_manager.cpython-310.pyc index b84a3af..c4626bf 100644 Binary files a/customtkinter/windows/widgets/font/__pycache__/font_manager.cpython-310.pyc and b/customtkinter/windows/widgets/font/__pycache__/font_manager.cpython-310.pyc differ diff --git a/customtkinter/windows/widgets/image/__pycache__/__init__.cpython-310.pyc b/customtkinter/windows/widgets/image/__pycache__/__init__.cpython-310.pyc index fc6e143..e2f9358 100644 Binary files a/customtkinter/windows/widgets/image/__pycache__/__init__.cpython-310.pyc and b/customtkinter/windows/widgets/image/__pycache__/__init__.cpython-310.pyc differ diff --git a/customtkinter/windows/widgets/image/__pycache__/ctk_image.cpython-310.pyc b/customtkinter/windows/widgets/image/__pycache__/ctk_image.cpython-310.pyc index 1f1b44b..9ca44bc 100644 Binary files a/customtkinter/windows/widgets/image/__pycache__/ctk_image.cpython-310.pyc and b/customtkinter/windows/widgets/image/__pycache__/ctk_image.cpython-310.pyc differ diff --git a/customtkinter/windows/widgets/scaling/__pycache__/__init__.cpython-310.pyc b/customtkinter/windows/widgets/scaling/__pycache__/__init__.cpython-310.pyc index 05da204..62a614f 100644 Binary files a/customtkinter/windows/widgets/scaling/__pycache__/__init__.cpython-310.pyc and b/customtkinter/windows/widgets/scaling/__pycache__/__init__.cpython-310.pyc differ diff --git a/customtkinter/windows/widgets/scaling/__pycache__/scaling_base_class.cpython-310.pyc b/customtkinter/windows/widgets/scaling/__pycache__/scaling_base_class.cpython-310.pyc index b113161..6ccb213 100644 Binary files a/customtkinter/windows/widgets/scaling/__pycache__/scaling_base_class.cpython-310.pyc and b/customtkinter/windows/widgets/scaling/__pycache__/scaling_base_class.cpython-310.pyc differ diff --git a/customtkinter/windows/widgets/scaling/__pycache__/scaling_tracker.cpython-310.pyc b/customtkinter/windows/widgets/scaling/__pycache__/scaling_tracker.cpython-310.pyc index d2887fa..41a0eb1 100644 Binary files a/customtkinter/windows/widgets/scaling/__pycache__/scaling_tracker.cpython-310.pyc and b/customtkinter/windows/widgets/scaling/__pycache__/scaling_tracker.cpython-310.pyc differ diff --git a/customtkinter/windows/widgets/theme/__pycache__/__init__.cpython-310.pyc b/customtkinter/windows/widgets/theme/__pycache__/__init__.cpython-310.pyc index 171f336..39be2a7 100644 Binary files a/customtkinter/windows/widgets/theme/__pycache__/__init__.cpython-310.pyc and b/customtkinter/windows/widgets/theme/__pycache__/__init__.cpython-310.pyc differ diff --git a/customtkinter/windows/widgets/theme/__pycache__/__init__.cpython-37.pyc b/customtkinter/windows/widgets/theme/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000..47788ad Binary files /dev/null and b/customtkinter/windows/widgets/theme/__pycache__/__init__.cpython-37.pyc differ diff --git a/customtkinter/windows/widgets/theme/__pycache__/theme_manager.cpython-310.pyc b/customtkinter/windows/widgets/theme/__pycache__/theme_manager.cpython-310.pyc index e707128..c59b595 100644 Binary files a/customtkinter/windows/widgets/theme/__pycache__/theme_manager.cpython-310.pyc and b/customtkinter/windows/widgets/theme/__pycache__/theme_manager.cpython-310.pyc differ diff --git a/customtkinter/windows/widgets/theme/__pycache__/theme_manager.cpython-37.pyc b/customtkinter/windows/widgets/theme/__pycache__/theme_manager.cpython-37.pyc new file mode 100644 index 0000000..5219102 Binary files /dev/null and b/customtkinter/windows/widgets/theme/__pycache__/theme_manager.cpython-37.pyc differ diff --git a/customtkinter/windows/widgets/utility/__pycache__/__init__.cpython-310.pyc b/customtkinter/windows/widgets/utility/__pycache__/__init__.cpython-310.pyc index 42608ea..436f0eb 100644 Binary files a/customtkinter/windows/widgets/utility/__pycache__/__init__.cpython-310.pyc and b/customtkinter/windows/widgets/utility/__pycache__/__init__.cpython-310.pyc differ diff --git a/customtkinter/windows/widgets/utility/__pycache__/utility_functions.cpython-310.pyc b/customtkinter/windows/widgets/utility/__pycache__/utility_functions.cpython-310.pyc index dc466e2..35ce824 100644 Binary files a/customtkinter/windows/widgets/utility/__pycache__/utility_functions.cpython-310.pyc and b/customtkinter/windows/widgets/utility/__pycache__/utility_functions.cpython-310.pyc differ diff --git a/main.py b/main.py index 0c8fafb..a1b20cf 100644 --- a/main.py +++ b/main.py @@ -64,11 +64,13 @@ class Expression: def valeurs_de_fonction(self, start, end): """ Calcul les valeurs entre start et end""" result = [] - for i in range(start, end+1): + pas = (end - start) / 1000 + while start <= end: try: - result.append((i, self.evalue(i))) + result.append((start, self.evalue(start))) except: pass + start += pas return result @@ -121,6 +123,18 @@ class App(ctk.CTk): self.fonction_frame = ctk.CTkFrame(self, fg_color="transparent") + self.fonction_bornes_frame = ctk.CTkFrame(self.fonction_frame, corner_radius=None) + + self.fonction_bornes_entry = ctk.CTkEntry(self.fonction_bornes_frame) + self.fonction_bornes_entry.insert(0, "-100,100") + self.fonction_bornes_entry.grid(sticky="ew", row=1, padx=10) + + self.fonction_bornes_text = ctk.CTkLabel(self.fonction_bornes_frame, text="Entrez les bornes de tracé: (min, max)") + self.fonction_bornes_text.grid(sticky="ew", row=0) + + self.fonction_bornes_frame.grid(sticky="ns", column=0, rowspan=2) + + self.fonction_screen = ctk.CTkCanvas(self.fonction_frame) self.fonction_screen.grid(sticky="nsew", column=1, row=0) self.fonction_entry = ctk.CTkEntry(self.fonction_frame) @@ -238,7 +252,7 @@ class App(ctk.CTk): ordonnee = max_x / (abs(min_x)+abs(max_x)) for i in range(20): # dessin des lignes verticales - if i == int(20*ordonnee): + if i == int(20 - 20*ordonnee): self.fonction_screen.create_line(0 + i * self.fonction_screen_width/20, 0 , 0 + i * self.fonction_screen_width/20, self.fonction_screen_height , fill='red', width=4) @@ -257,7 +271,7 @@ class App(ctk.CTk): nb_abscisse_lines = int(20*ratio) # nombre de lignes horizontales à tracer for i in range(nb_abscisse_lines): # dessin des lignes horizontales - if i == int(nb_abscisse_lines * abscisse): # tracer de l'axe des abscisses + if i == math.ceil(nb_abscisse_lines * abscisse): # tracer de l'axe des abscisses self.fonction_screen.create_line(0, 0 + i * self.fonction_screen_width/20 , self.fonction_screen_width , 0 + i * self.fonction_screen_width/20, fill='red' @@ -292,12 +306,13 @@ class App(ctk.CTk): def draw_graph(self): """Dessine les points du graphique""" self.fonction_screen.delete('all') - fonction_points = npi2tree(inf2npi(parse_string_to_list(self.fonction_entry.get()))).valeurs_de_fonction(-100, 100) + min_x, max_x = map(int, self.fonction_bornes_entry.get().split(',')) + fonction_points = npi2tree(inf2npi(parse_string_to_list(self.fonction_entry.get()))).valeurs_de_fonction(min_x, max_x) max_y = max(fonction_points, key=lambda item: item[1])[1] min_y = min(fonction_points, key=lambda item: item[1])[1] - self.draw_framing(-1000, 1000, min_y, max_y) - for x, y in fonction_points: - image_x = self.fonction_screen_width / 2 + x * (self.fonction_screen_width/len(fonction_points)) + self.draw_framing(min_x, max_x, min_y, max_y) + for i, (x, y) in enumerate(fonction_points): + image_x = i * (self.fonction_screen_width/len(fonction_points)) image_y = self.fonction_screen_height - (y - min_y) * self.fonction_screen_height / (abs(max_y)+abs(min_y)) self.fonction_screen.create_rectangle(image_x, image_y, image_x, image_y) @@ -319,11 +334,9 @@ def parse_string_to_list(text: str) -> list: if len(buffer_function) == 0: number_first = True elif char.isalpha(): - print(char) buffer_function += char else: if number_first: - print("number", char) result.append(float(buffer_number)) buffer_number = "" number_first = False @@ -332,7 +345,6 @@ def parse_string_to_list(text: str) -> list: result.append(buffer_function) buffer_function = "" elif char == '(': - print("()") result.append('*') else: @@ -351,7 +363,6 @@ def parse_string_to_list(text: str) -> list: result.append(buffer_function) elif len(buffer_function) != 0: result.append(buffer_function) - print(result) return result def npi2tree(expr: list) -> Expression: @@ -399,7 +410,6 @@ def inf2npi(expr: list) -> list: operator_stack.empiler(val) while not operator_stack.est_vide(): output.append(operator_stack.depiler()) - print(output) return output