ctk_input_dialog.py 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. from typing import Union, Tuple, Optional
  2. from .widgets import CTkLabel
  3. from .widgets import CTkEntry
  4. from .widgets import CTkButton
  5. from .widgets.theme import ThemeManager
  6. from .ctk_toplevel import CTkToplevel
  7. from .widgets.font import CTkFont
  8. class CTkInputDialog(CTkToplevel):
  9. """
  10. Dialog with extra window, message, entry widget, cancel and ok button.
  11. For detailed information check out the documentation.
  12. """
  13. def __init__(self,
  14. fg_color: Optional[Union[str, Tuple[str, str]]] = None,
  15. text_color: Optional[Union[str, Tuple[str, str]]] = None,
  16. button_fg_color: Optional[Union[str, Tuple[str, str]]] = None,
  17. button_hover_color: Optional[Union[str, Tuple[str, str]]] = None,
  18. button_text_color: Optional[Union[str, Tuple[str, str]]] = None,
  19. entry_fg_color: Optional[Union[str, Tuple[str, str]]] = None,
  20. entry_border_color: Optional[Union[str, Tuple[str, str]]] = None,
  21. entry_text_color: Optional[Union[str, Tuple[str, str]]] = None,
  22. title: str = "CTkDialog",
  23. font: Optional[Union[tuple, CTkFont]] = None,
  24. text: str = "CTkDialog"):
  25. super().__init__(fg_color=fg_color)
  26. self._fg_color = ThemeManager.theme["CTkToplevel"]["fg_color"] if fg_color is None else self._check_color_type(fg_color)
  27. self._text_color = ThemeManager.theme["CTkLabel"]["text_color"] if text_color is None else self._check_color_type(button_hover_color)
  28. self._button_fg_color = ThemeManager.theme["CTkButton"]["fg_color"] if button_fg_color is None else self._check_color_type(button_fg_color)
  29. self._button_hover_color = ThemeManager.theme["CTkButton"]["hover_color"] if button_hover_color is None else self._check_color_type(button_hover_color)
  30. self._button_text_color = ThemeManager.theme["CTkButton"]["text_color"] if button_text_color is None else self._check_color_type(button_text_color)
  31. self._entry_fg_color = ThemeManager.theme["CTkEntry"]["fg_color"] if entry_fg_color is None else self._check_color_type(entry_fg_color)
  32. self._entry_border_color = ThemeManager.theme["CTkEntry"]["border_color"] if entry_border_color is None else self._check_color_type(entry_border_color)
  33. self._entry_text_color = ThemeManager.theme["CTkEntry"]["text_color"] if entry_text_color is None else self._check_color_type(entry_text_color)
  34. self._user_input: Union[str, None] = None
  35. self._running: bool = False
  36. self._title = title
  37. self._text = text
  38. self._font = font
  39. self.title(self._title)
  40. self.lift() # lift window on top
  41. self.attributes("-topmost", True) # stay on top
  42. self.protocol("WM_DELETE_WINDOW", self._on_closing)
  43. self.after(10, self._create_widgets) # create widgets with slight delay, to avoid white flickering of background
  44. self.resizable(False, False)
  45. self.grab_set() # make other windows not clickable
  46. def _create_widgets(self):
  47. self.grid_columnconfigure((0, 1), weight=1)
  48. self.rowconfigure(0, weight=1)
  49. self._label = CTkLabel(master=self,
  50. width=300,
  51. wraplength=300,
  52. fg_color="transparent",
  53. text_color=self._text_color,
  54. text=self._text,
  55. font=self._font)
  56. self._label.grid(row=0, column=0, columnspan=2, padx=20, pady=20, sticky="ew")
  57. self._entry = CTkEntry(master=self,
  58. width=230,
  59. fg_color=self._entry_fg_color,
  60. border_color=self._entry_border_color,
  61. text_color=self._entry_text_color,
  62. font=self._font)
  63. self._entry.grid(row=1, column=0, columnspan=2, padx=20, pady=(0, 20), sticky="ew")
  64. self._ok_button = CTkButton(master=self,
  65. width=100,
  66. border_width=0,
  67. fg_color=self._button_fg_color,
  68. hover_color=self._button_hover_color,
  69. text_color=self._button_text_color,
  70. text='Ok',
  71. font=self._font,
  72. command=self._ok_event)
  73. self._ok_button.grid(row=2, column=0, columnspan=1, padx=(20, 10), pady=(0, 20), sticky="ew")
  74. self._cancel_button = CTkButton(master=self,
  75. width=100,
  76. border_width=0,
  77. fg_color=self._button_fg_color,
  78. hover_color=self._button_hover_color,
  79. text_color=self._button_text_color,
  80. text='Cancel',
  81. font=self._font,
  82. command=self._cancel_event)
  83. self._cancel_button.grid(row=2, column=1, columnspan=1, padx=(10, 20), pady=(0, 20), sticky="ew")
  84. self.after(150, lambda: self._entry.focus()) # set focus to entry with slight delay, otherwise it won't work
  85. self._entry.bind("<Return>", self._ok_event)
  86. def _ok_event(self, event=None):
  87. self._user_input = self._entry.get()
  88. self.grab_release()
  89. self.destroy()
  90. def _on_closing(self):
  91. self.grab_release()
  92. self.destroy()
  93. def _cancel_event(self):
  94. self.grab_release()
  95. self.destroy()
  96. def get_input(self):
  97. self.master.wait_window(self)
  98. return self._user_input