mirror of
https://github.com/TomSchimansky/CustomTkinter.git
synced 2023-08-10 21:13:13 +03:00
enhanced inherit structure
This commit is contained in:
parent
c2a5b4881e
commit
302313916a
@ -29,6 +29,7 @@ ToDo:
|
|||||||
- Changed 'orient' attribute of CTkProgressBar and CTkSlider to 'orientation'
|
- Changed 'orient' attribute of CTkProgressBar and CTkSlider to 'orientation'
|
||||||
- Width and height attributes of CTkCheckBox, CTkRadioButton, CTkSwitch now describe the outer dimensions of the whole widget. The button/switch size is described by separate attributes like checkbox_width, checkbox_height
|
- Width and height attributes of CTkCheckBox, CTkRadioButton, CTkSwitch now describe the outer dimensions of the whole widget. The button/switch size is described by separate attributes like checkbox_width, checkbox_height
|
||||||
- font attribute must be tuple or CTkFont now, all size values are measured in pixel now
|
- font attribute must be tuple or CTkFont now, all size values are measured in pixel now
|
||||||
|
- Changed dictionary key 'window_bg_color' to 'window' in theme files
|
||||||
|
|
||||||
### Removed
|
### Removed
|
||||||
- Removed setter and getter functions like set_text in CTkButton
|
- Removed setter and getter functions like set_text in CTkButton
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"color": {
|
"color": {
|
||||||
"window_bg_color": ["#EBEBEC", "#212325"],
|
"window": ["#EBEBEC", "#212325"],
|
||||||
"button": ["#3B8ED0", "#1F6AA5"],
|
"button": ["#3B8ED0", "#1F6AA5"],
|
||||||
"button_hover": ["#36719F", "#144870"],
|
"button_hover": ["#36719F", "#144870"],
|
||||||
"button_border": ["#3E454A", "#949A9F"],
|
"button_border": ["#3E454A", "#949A9F"],
|
||||||
|
@ -2,84 +2,75 @@ from typing import Union, Tuple
|
|||||||
|
|
||||||
from .widgets.ctk_label import CTkLabel
|
from .widgets.ctk_label import CTkLabel
|
||||||
from .widgets.ctk_entry import CTkEntry
|
from .widgets.ctk_entry import CTkEntry
|
||||||
from .ctk_toplevel import CTkToplevel
|
|
||||||
from .widgets.ctk_button import CTkButton
|
from .widgets.ctk_button import CTkButton
|
||||||
from .widgets.appearance_mode.appearance_mode_tracker import AppearanceModeTracker
|
|
||||||
from .widgets.theme.theme_manager import ThemeManager
|
from .widgets.theme.theme_manager import ThemeManager
|
||||||
|
from .ctk_toplevel import CTkToplevel
|
||||||
|
|
||||||
|
|
||||||
class CTkInputDialog:
|
class CTkInputDialog(CTkToplevel):
|
||||||
"""
|
"""
|
||||||
Dialog with extra window, message, entry widget, cancel and ok button.
|
Dialog with extra window, message, entry widget, cancel and ok button.
|
||||||
For detailed information check out the documentation.
|
For detailed information check out the documentation.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, *args,
|
def __init__(self,
|
||||||
fg_color: Union[str, Tuple[str, str]] = "default_theme",
|
|
||||||
hover_color: Union[str, Tuple[str, str]] = "default_theme",
|
|
||||||
border_color: Union[str, Tuple[str, str]] = "default_theme",
|
|
||||||
|
|
||||||
master: any = None,
|
master: any = None,
|
||||||
|
fg_color: Union[str, Tuple[str, str]] = "default_theme",
|
||||||
|
button_fg_color: Union[str, Tuple[str, str]] = "default_theme",
|
||||||
|
button_hover_color: Union[str, Tuple[str, str]] = "default_theme",
|
||||||
|
text_color: Union[str, Tuple[str, str]] = "default_theme",
|
||||||
|
|
||||||
title: str = "CTkDialog",
|
title: str = "CTkDialog",
|
||||||
text: str = "CTkDialog"):
|
text: str = "CTkDialog"):
|
||||||
|
|
||||||
self._appearance_mode = AppearanceModeTracker.get_mode() # 0: "Light" 1: "Dark"
|
super().__init__(master=master, fg_color=fg_color)
|
||||||
|
|
||||||
if len(args) > 0 and master is None:
|
|
||||||
self.master = args[0]
|
|
||||||
elif master is not None:
|
|
||||||
self.master = master
|
|
||||||
else:
|
|
||||||
raise ValueError("master argument is missing")
|
|
||||||
|
|
||||||
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
|
|
||||||
self._border_color = ThemeManager.theme["color"]["button_hover"] if border_color == "default_theme" else border_color
|
|
||||||
|
|
||||||
|
self._fg_color = ThemeManager.theme["color"]["window"] if fg_color == "default_theme" else fg_color
|
||||||
|
self._button_fg_color = ThemeManager.theme["color"]["button"] if button_fg_color == "default_theme" else button_fg_color
|
||||||
|
self._button_hover_color = ThemeManager.theme["color"]["button_hover"] if button_hover_color == "default_theme" else button_hover_color
|
||||||
|
self._text_color = ThemeManager.theme["color"]["text"] if button_hover_color == "default_theme" else button_hover_color
|
||||||
self._user_input: Union[str, None] = None
|
self._user_input: Union[str, None] = None
|
||||||
self._running: bool = False
|
self._running: bool = False
|
||||||
self._height: int = len(text.split("\n")) * 20 + 150
|
self._height: int = len(text.split("\n")) * 20 + 150
|
||||||
self._text = text
|
self._text = text
|
||||||
|
|
||||||
self._toplevel_window = CTkToplevel(self.master)
|
self.geometry(f"{280}x{self._height}")
|
||||||
self._toplevel_window.geometry(f"{280}x{self._height}")
|
self.minsize(280, self._height)
|
||||||
self._toplevel_window.minsize(280, self._height)
|
self.maxsize(280, self._height)
|
||||||
self._toplevel_window.maxsize(280, self._height)
|
self.title(title)
|
||||||
self._toplevel_window.title(title)
|
self.focus_force()
|
||||||
self._toplevel_window.focus_force()
|
self.grab_set() # make other windows not clickable
|
||||||
self._toplevel_window.grab_set() # make other windows not clickable
|
self.lift() # lift window on top
|
||||||
self._toplevel_window.lift() # lift window on top
|
self.attributes("-topmost", True) # stay on top
|
||||||
self._toplevel_window.attributes("-topmost", True) # stay on top
|
self.protocol("WM_DELETE_WINDOW", self._on_closing)
|
||||||
self._toplevel_window.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._toplevel_window.after(10, self._create_widgets) # create widgets with slight delay, to avoid white flickering of background
|
|
||||||
|
|
||||||
def _create_widgets(self):
|
def _create_widgets(self):
|
||||||
|
|
||||||
self._toplevel_window.grid_columnconfigure((0, 1), weight=1)
|
self.grid_columnconfigure((0, 1), weight=1)
|
||||||
self._toplevel_window.rowconfigure(0, weight=1)
|
self.rowconfigure(0, weight=1)
|
||||||
|
|
||||||
self._myLabel = CTkLabel(master=self._toplevel_window,
|
self._myLabel = CTkLabel(master=self,
|
||||||
text=self._text,
|
text=self._text,
|
||||||
width=300,
|
width=300,
|
||||||
fg_color=None,
|
fg_color=None,
|
||||||
height=self._height-100)
|
height=self._height-100)
|
||||||
self._myLabel.grid(row=0, column=0, columnspan=2, padx=20, pady=20, sticky="ew")
|
self._myLabel.grid(row=0, column=0, columnspan=2, padx=20, pady=20, sticky="ew")
|
||||||
|
|
||||||
self._entry = CTkEntry(master=self._toplevel_window,
|
self._entry = CTkEntry(master=self,
|
||||||
width=230)
|
width=230)
|
||||||
self._entry.grid(row=1, column=0, columnspan=2, padx=20, pady=(0, 20), sticky="ew")
|
self._entry.grid(row=1, column=0, columnspan=2, padx=20, pady=(0, 20), sticky="ew")
|
||||||
|
|
||||||
self._ok_button = CTkButton(master=self._toplevel_window,
|
self._ok_button = CTkButton(master=self,
|
||||||
text='Ok',
|
text='Ok',
|
||||||
width=100,
|
width=100,
|
||||||
command=self._ok_event,
|
command=self._ok_event,
|
||||||
fg_color=self._fg_color,
|
fg_color=self._fg_color,
|
||||||
hover_color=self._hover_color,
|
hover_color=self._hover_color,
|
||||||
border_color=self._border_color)
|
border_width=0)
|
||||||
self._ok_button.grid(row=2, column=0, columnspan=1, padx=(20, 10), pady=(0, 20), sticky="ew")
|
self._ok_button.grid(row=2, column=0, columnspan=1, padx=(20, 10), pady=(0, 20), sticky="ew")
|
||||||
|
|
||||||
self._cancel_button = CTkButton(master=self._toplevel_window,
|
self._cancel_button = CTkButton(master=self,
|
||||||
text='Cancel',
|
text='Cancel',
|
||||||
width=100,
|
width=100,
|
||||||
command=self._cancel_event,
|
command=self._cancel_event,
|
||||||
@ -93,17 +84,17 @@ class CTkInputDialog:
|
|||||||
|
|
||||||
def _ok_event(self, event=None):
|
def _ok_event(self, event=None):
|
||||||
self._user_input = self._entry.get()
|
self._user_input = self._entry.get()
|
||||||
self._toplevel_window.grab_release()
|
self.grab_release()
|
||||||
self._toplevel_window.destroy()
|
self.destroy()
|
||||||
|
|
||||||
def _on_closing(self):
|
def _on_closing(self):
|
||||||
self._toplevel_window.grab_release()
|
self.grab_release()
|
||||||
self._toplevel_window.destroy()
|
self.destroy()
|
||||||
|
|
||||||
def _cancel_event(self):
|
def _cancel_event(self):
|
||||||
self._toplevel_window.grab_release()
|
self.grab_release()
|
||||||
self._toplevel_window.destroy()
|
self.destroy()
|
||||||
|
|
||||||
def get_input(self):
|
def get_input(self):
|
||||||
self.master.wait_window(self._toplevel_window)
|
self.master.wait_window(self)
|
||||||
return self._user_input
|
return self._user_input
|
||||||
|
@ -48,7 +48,7 @@ class CTk(tkinter.Tk, CTkAppearanceModeBaseClass, CTkScalingBaseClass):
|
|||||||
self._max_height: int = 1_000_000
|
self._max_height: int = 1_000_000
|
||||||
self._last_resizable_args: Union[Tuple[list, dict], None] = None # (args, kwargs)
|
self._last_resizable_args: Union[Tuple[list, dict], None] = None # (args, kwargs)
|
||||||
|
|
||||||
self._fg_color = ThemeManager.theme["color"]["window_bg_color"] if fg_color == "default_theme" else fg_color
|
self._fg_color = ThemeManager.theme["color"]["window"] if fg_color == "default_theme" else fg_color
|
||||||
|
|
||||||
# set bg of tkinter.Tk
|
# set bg of tkinter.Tk
|
||||||
super().configure(bg=self._apply_appearance_mode(self._fg_color))
|
super().configure(bg=self._apply_appearance_mode(self._fg_color))
|
||||||
|
@ -32,7 +32,7 @@ class CTkToplevel(tkinter.Toplevel, CTkAppearanceModeBaseClass, CTkScalingBaseCl
|
|||||||
|
|
||||||
self._enable_macos_dark_title_bar()
|
self._enable_macos_dark_title_bar()
|
||||||
|
|
||||||
# call init methods of super classees
|
# call init methods of super classes
|
||||||
super().__init__(*args, **pop_from_dict_by_set(kwargs, self._valid_tk_toplevel_arguments))
|
super().__init__(*args, **pop_from_dict_by_set(kwargs, self._valid_tk_toplevel_arguments))
|
||||||
CTkAppearanceModeBaseClass.__init__(self)
|
CTkAppearanceModeBaseClass.__init__(self)
|
||||||
CTkScalingBaseClass.__init__(self, scaling_type="window")
|
CTkScalingBaseClass.__init__(self, scaling_type="window")
|
||||||
@ -46,7 +46,7 @@ class CTkToplevel(tkinter.Toplevel, CTkAppearanceModeBaseClass, CTkScalingBaseCl
|
|||||||
self._max_height: int = 1_000_000
|
self._max_height: int = 1_000_000
|
||||||
self._last_resizable_args: Union[Tuple[list, dict], None] = None # (args, kwargs)
|
self._last_resizable_args: Union[Tuple[list, dict], None] = None # (args, kwargs)
|
||||||
|
|
||||||
self._fg_color = ThemeManager.theme["color"]["window_bg_color"] if fg_color == "default_theme" else fg_color
|
self._fg_color = ThemeManager.theme["color"]["window"] if fg_color == "default_theme" else fg_color
|
||||||
|
|
||||||
# set bg color of tkinter.Toplevel
|
# set bg color of tkinter.Toplevel
|
||||||
super().configure(bg=self._apply_appearance_mode(self._fg_color))
|
super().configure(bg=self._apply_appearance_mode(self._fg_color))
|
||||||
|
@ -21,7 +21,7 @@ class AppearanceModeTracker:
|
|||||||
callback_list = []
|
callback_list = []
|
||||||
app_list = []
|
app_list = []
|
||||||
update_loop_running = False
|
update_loop_running = False
|
||||||
update_loop_interval = 500 # milliseconds
|
update_loop_interval = 30 # milliseconds
|
||||||
|
|
||||||
appearance_mode_set_by = "system"
|
appearance_mode_set_by = "system"
|
||||||
appearance_mode = 0 # Light (standard)
|
appearance_mode = 0 # Light (standard)
|
||||||
|
@ -71,12 +71,12 @@ class DropdownMenu(tkinter.Menu, CTkAppearanceModeBaseClass):
|
|||||||
elif sys.platform.startswith("win"):
|
elif sys.platform.startswith("win"):
|
||||||
super().configure(tearoff=False,
|
super().configure(tearoff=False,
|
||||||
relief="flat",
|
relief="flat",
|
||||||
activebackground=ThemeManager._apply_appearance_mode(self._hover_color, self._appearance_mode),
|
activebackground=self._apply_appearance_mode(self._hover_color),
|
||||||
borderwidth=self._apply_widget_scaling(4),
|
borderwidth=self._apply_widget_scaling(4),
|
||||||
activeborderwidth=self._apply_widget_scaling(4),
|
activeborderwidth=self._apply_widget_scaling(4),
|
||||||
bg=ThemeManager._apply_appearance_mode(self._fg_color, self._appearance_mode),
|
bg=self._apply_appearance_mode(self._fg_color),
|
||||||
fg=ThemeManager._apply_appearance_mode(self._text_color, self._appearance_mode),
|
fg=self._apply_appearance_mode(self._text_color),
|
||||||
activeforeground=ThemeManager._apply_appearance_mode(self._text_color, self._appearance_mode),
|
activeforeground=self._apply_appearance_mode(self._text_color),
|
||||||
font=self._apply_font_scaling(self._font),
|
font=self._apply_font_scaling(self._font),
|
||||||
cursor="hand2")
|
cursor="hand2")
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user