From 2c31f18dc16df8b554c947966410522d3bb129ee Mon Sep 17 00:00:00 2001 From: Tom Schimansky Date: Fri, 11 Nov 2022 00:06:25 +0100 Subject: [PATCH] renewed CTkInputDialog --- customtkinter/windows/ctk_input_dialog.py | 77 +++++++++++-------- customtkinter/windows/ctk_toplevel.py | 4 +- customtkinter/windows/widgets/ctk_label.py | 12 ++- .../windows/widgets/ctk_segmented_button.py | 2 +- examples/complex_example.py | 2 +- 5 files changed, 59 insertions(+), 38 deletions(-) diff --git a/customtkinter/windows/ctk_input_dialog.py b/customtkinter/windows/ctk_input_dialog.py index e594716..10e5c96 100644 --- a/customtkinter/windows/ctk_input_dialog.py +++ b/customtkinter/windows/ctk_input_dialog.py @@ -1,4 +1,4 @@ -from typing import Union, Tuple +from typing import Union, Tuple, Optional from .widgets.ctk_label import CTkLabel from .widgets.ctk_entry import CTkEntry @@ -14,69 +14,80 @@ class CTkInputDialog(CTkToplevel): """ def __init__(self, - master: any = None, - fg_color: Union[str, Tuple[str, str]] = "default", - button_fg_color: Union[str, Tuple[str, str]] = "default", - button_hover_color: Union[str, Tuple[str, str]] = "default", - text_color: Union[str, Tuple[str, str]] = "default", + fg_color: Optional[Union[str, Tuple[str, str]]] = None, + text_color: Optional[Union[str, Tuple[str, str]]] = None, + button_fg_color: Optional[Union[str, Tuple[str, str]]] = None, + button_hover_color: Optional[Union[str, Tuple[str, str]]] = None, + button_text_color: Optional[Union[str, Tuple[str, str]]] = None, + entry_fg_color: Optional[Union[str, Tuple[str, str]]] = None, + entry_border_color: Optional[Union[str, Tuple[str, str]]] = None, + entry_text_color: Optional[Union[str, Tuple[str, str]]] = None, title: str = "CTkDialog", text: str = "CTkDialog"): - super().__init__(master=master, fg_color=fg_color) + super().__init__(fg_color=fg_color) + + self._fg_color = ThemeManager.theme["color"]["window"] if fg_color is None else self._check_color_type(fg_color) + self._text_color = ThemeManager.theme["color"]["text"] if text_color is None else self._check_color_type(button_hover_color) + self._button_fg_color = ThemeManager.theme["color"]["button"] if button_fg_color is None else self._check_color_type(button_fg_color) + self._button_hover_color = ThemeManager.theme["color"]["button_hover"] if button_hover_color is None else self._check_color_type(button_hover_color) + self._button_text_color = ThemeManager.theme["color"]["text"] if button_text_color is None else self._check_color_type(button_text_color) + self._entry_fg_color = ThemeManager.theme["color"]["entry"] if entry_fg_color is None else self._check_color_type(entry_fg_color) + self._entry_border_color = ThemeManager.theme["color"]["entry_border"] if entry_border_color is None else self._check_color_type(entry_border_color) + self._entry_text_color = ThemeManager.theme["color"]["text"] if entry_text_color is None else self._check_color_type(entry_text_color) - self._fg_color = ThemeManager.theme["color"]["window"] if fg_color == "default" else fg_color - self._button_fg_color = ThemeManager.theme["color"]["button"] if button_fg_color == "default" else button_fg_color - self._button_hover_color = ThemeManager.theme["color"]["button_hover"] if button_hover_color == "default" else button_hover_color - self._text_color = ThemeManager.theme["color"]["text"] if button_hover_color == "default" else button_hover_color self._user_input: Union[str, None] = None self._running: bool = False - self._height: int = len(text.split("\n")) * 20 + 150 self._text = text - self.geometry(f"{280}x{self._height}") - self.minsize(280, self._height) - self.maxsize(280, self._height) self.title(title) self.focus_force() self.grab_set() # make other windows not clickable self.lift() # lift window on top self.attributes("-topmost", True) # stay on top self.protocol("WM_DELETE_WINDOW", self._on_closing) - self.after(10, self._create_widgets) # create widgets with slight delay, to avoid white flickering of background + self.after(0, self._create_widgets) # create widgets with slight delay, to avoid white flickering of background + self.after(500, lambda: self.resizable(False, False)) def _create_widgets(self): self.grid_columnconfigure((0, 1), weight=1) self.rowconfigure(0, weight=1) - self._myLabel = CTkLabel(master=self, - text=self._text, - width=300, - fg_color=None, - height=self._height-100) - self._myLabel.grid(row=0, column=0, columnspan=2, padx=20, pady=20, sticky="ew") + self._label = CTkLabel(master=self, + width=300, + wraplength=300, + fg_color="transparent", + text_color=self._text_color, + text=self._text,) + self._label.grid(row=0, column=0, columnspan=2, padx=20, pady=20, sticky="ew") self._entry = CTkEntry(master=self, - width=230) + width=230, + fg_color=self._entry_fg_color, + border_color=self._entry_border_color, + text_color=self._entry_text_color) self._entry.grid(row=1, column=0, columnspan=2, padx=20, pady=(0, 20), sticky="ew") self._ok_button = CTkButton(master=self, - text='Ok', width=100, - command=self._ok_event, - fg_color=self._fg_color, - hover_color=self._hover_color, - border_width=0) + border_width=0, + fg_color=self._button_fg_color, + hover_color=self._button_hover_color, + text_color=self._button_text_color, + text='Ok', + command=self._ok_event) self._ok_button.grid(row=2, column=0, columnspan=1, padx=(20, 10), pady=(0, 20), sticky="ew") self._cancel_button = CTkButton(master=self, - text='Cancel', width=100, - command=self._cancel_event, - fg_color=self._fg_color, - hover_color=self._hover_color, - border_color=self._border_color) + border_width=0, + fg_color=self._button_fg_color, + hover_color=self._button_hover_color, + text_color=self._button_text_color, + text='Cancel', + command=self._ok_event) self._cancel_button.grid(row=2, column=1, columnspan=1, padx=(10, 20), pady=(0, 20), sticky="ew") self._entry.focus_force() diff --git a/customtkinter/windows/ctk_toplevel.py b/customtkinter/windows/ctk_toplevel.py index 2075618..1a50c0a 100644 --- a/customtkinter/windows/ctk_toplevel.py +++ b/customtkinter/windows/ctk_toplevel.py @@ -20,8 +20,8 @@ class CTkToplevel(tkinter.Toplevel, CTkAppearanceModeBaseClass, CTkScalingBaseCl """ _valid_tk_toplevel_arguments: set = {"bd", "borderwidth", "class", "container", "cursor", "height", - "highlightbackground", "highlightthickness", "menu", "relief", - "screen", "takefocus", "use", "visual", "width"} + "highlightbackground", "highlightthickness", "menu", "relief", + "screen", "takefocus", "use", "visual", "width"} _deactivate_macos_window_header_manipulation: bool = False _deactivate_windows_window_header_manipulation: bool = False diff --git a/customtkinter/windows/widgets/ctk_label.py b/customtkinter/windows/widgets/ctk_label.py index a9d5161..9e972fa 100644 --- a/customtkinter/windows/widgets/ctk_label.py +++ b/customtkinter/windows/widgets/ctk_label.py @@ -19,7 +19,7 @@ class CTkLabel(CTkBaseClass): # attributes that are passed to and managed by the tkinter entry only: _valid_tk_label_attributes = {"cursor", "justify", "padx", "pady", - "textvariable", "state", "takefocus", "underline", "wraplength"} + "textvariable", "state", "takefocus", "underline"} def __init__(self, master: any, @@ -36,6 +36,7 @@ class CTkLabel(CTkBaseClass): image: Union[tkinter.PhotoImage, CTkImage, None] = None, compound: str = "center", anchor: str = "center", # label anchor: center, n, e, s, w + wraplength: int = 0, **kwargs): # transfer basic functionality (_bg_color, size, __appearance_mode, scaling) to CTkBaseClass @@ -51,6 +52,7 @@ class CTkLabel(CTkBaseClass): # text self._anchor = anchor self._text = text + self._wraplength = wraplength # image self._image = self._check_image_type(image) @@ -81,6 +83,7 @@ class CTkLabel(CTkBaseClass): borderwidth=0, anchor=self._anchor, compound=self._compound, + wraplength=self._apply_widget_scaling(self._wraplength), text=self._text, font=self._apply_font_scaling(self._font)) self._label.configure(**pop_from_dict_by_set(kwargs, self._valid_tk_label_attributes)) @@ -96,6 +99,7 @@ class CTkLabel(CTkBaseClass): self._canvas.configure(width=self._apply_widget_scaling(self._desired_width), height=self._apply_widget_scaling(self._desired_height)) self._label.configure(font=self._apply_font_scaling(self._font)) + self._label.configure(wraplength=self._apply_widget_scaling(self._wraplength)) self._create_grid() self._draw(no_color_updates=True) @@ -208,6 +212,10 @@ class CTkLabel(CTkBaseClass): self._label.configure(anchor=self._anchor) self._create_grid() + if "wraplength" in kwargs: + self._wraplength = kwargs.pop("wraplength") + self._label.configure(wraplength=self._apply_widget_scaling(self._wraplength)) + self._label.configure(**pop_from_dict_by_set(kwargs, self._valid_tk_label_attributes)) # configure tkinter.Label super().configure(require_redraw=require_redraw, **kwargs) # configure CTkBaseClass @@ -230,6 +238,8 @@ class CTkLabel(CTkBaseClass): return self._compound elif attribute_name == "anchor": return self._anchor + elif attribute_name == "wraplength": + return self._wraplength elif attribute_name in self._valid_tk_label_attributes: return self._label.cget(attribute_name) # cget of tkinter.Label diff --git a/customtkinter/windows/widgets/ctk_segmented_button.py b/customtkinter/windows/widgets/ctk_segmented_button.py index da12d76..7aa186a 100644 --- a/customtkinter/windows/widgets/ctk_segmented_button.py +++ b/customtkinter/windows/widgets/ctk_segmented_button.py @@ -84,7 +84,7 @@ class CTkSegmentedButton(CTkFrame): self._variable_callback_name = self._variable.trace_add("write", self._variable_callback) self.set(self._variable.get(), from_variable_callback=True) - super().configure(corner_radius=self._sb_corner_radius, fg_color="red") + super().configure(corner_radius=self._sb_corner_radius, fg_color="transparent") def destroy(self): if self._variable is not None: # remove old callback diff --git a/examples/complex_example.py b/examples/complex_example.py index ab091ee..e3742aa 100644 --- a/examples/complex_example.py +++ b/examples/complex_example.py @@ -138,7 +138,7 @@ class App(customtkinter.CTk): self.seg_button_1.set("Value 2") def open_input_dialog(self): - dialog = customtkinter.CTkInputDialog(master=self, text="Type in a number:", title="CTkInputDialog") + dialog = customtkinter.CTkInputDialog(text="Type in a number:"*500, title="CTkInputDialog") print("CTkInputDialog:", dialog.get_input()) def change_appearance_mode(self, new_appearance_mode: str):