diff --git a/customtkinter/__init__.py b/customtkinter/__init__.py index ac1a8b70..a2cd1519 100644 --- a/customtkinter/__init__.py +++ b/customtkinter/__init__.py @@ -39,6 +39,7 @@ from .windows import CTk from .windows import CTkToplevel from .windows import CTkInputDialog +from .windows import CTkAlertDialog # import font classes from .windows.widgets.font import CTkFont diff --git a/customtkinter/windows/__init__.py b/customtkinter/windows/__init__.py index ca681b72..050ca9fe 100644 --- a/customtkinter/windows/__init__.py +++ b/customtkinter/windows/__init__.py @@ -1,3 +1,4 @@ from .ctk_tk import CTk from .ctk_toplevel import CTkToplevel from .ctk_input_dialog import CTkInputDialog +from .ctk_alert_dialog import CTkAlertDialog diff --git a/customtkinter/windows/ctk_alert_dialog.py b/customtkinter/windows/ctk_alert_dialog.py new file mode 100644 index 00000000..db668730 --- /dev/null +++ b/customtkinter/windows/ctk_alert_dialog.py @@ -0,0 +1,100 @@ +from typing import Union, Tuple, Optional + +from .widgets import CTkLabel +from .widgets import CTkButton +from .widgets.theme import ThemeManager +from .ctk_toplevel import CTkToplevel +from .widgets.font import CTkFont + + +class CTkAlertDialog(CTkToplevel): + """ + Dialog with extra window, message, cancel and ok button. + For detailed information check out the documentation. + """ + + def __init__(self, + 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, + title: str = "CTkDialog", + font: Optional[Union[tuple, CTkFont]] = None, + text: str = "CTkDialog"): + + super().__init__(fg_color=fg_color) + + self._fg_color = ThemeManager.theme["CTkToplevel"]["fg_color"] if fg_color is None else self._check_color_type(fg_color) + self._text_color = ThemeManager.theme["CTkLabel"]["text_color"] if text_color is None else self._check_color_type(button_hover_color) + self._button_fg_color = ThemeManager.theme["CTkButton"]["fg_color"] if button_fg_color is None else self._check_color_type(button_fg_color) + self._button_hover_color = ThemeManager.theme["CTkButton"]["hover_color"] if button_hover_color is None else self._check_color_type(button_hover_color) + self._button_text_color = ThemeManager.theme["CTkButton"]["text_color"] if button_text_color is None else self._check_color_type(button_text_color) + self._is_ok: bool = False + self._running: bool = False + self._title = title + self._text = text + self._font = font + + self.title(self._title) + 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.resizable(False, False) + self.grab_set() # make other windows not clickable + + def _create_widgets(self): + self.grid_columnconfigure((0, 1), weight=1) + self.rowconfigure(0, weight=1) + + self._label = CTkLabel(master=self, + width=300, + wraplength=300, + fg_color="transparent", + text_color=self._text_color, + text=self._text, + font=self._font) + self._label.grid(row=0, column=0, columnspan=2, padx=20, pady=20, sticky="ew") + + self._ok_button = CTkButton(master=self, + width=100, + border_width=0, + fg_color=self._button_fg_color, + hover_color=self._button_hover_color, + text_color=self._button_text_color, + text='Ok', + font=self._font, + 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, + width=100, + border_width=0, + fg_color=self._button_fg_color, + hover_color=self._button_hover_color, + text_color=self._button_text_color, + text='Cancel', + font=self._font, + command=self._cancel_event) + self._cancel_button.grid(row=2, column=1, columnspan=1, padx=(10, 20), pady=(0, 20), sticky="ew") + + + def _ok_event(self, event=None): + self._is_ok = True + self.grab_release() + self.destroy() + + def _on_closing(self): + self.grab_release() + self.destroy() + + def _cancel_event(self): + self._is_ok = False + self.grab_release() + self.destroy() + + def get_state(self): + self.master.wait_window(self) + return self._is_ok +