enhanced inherit structure

This commit is contained in:
Tom Schimansky 2022-10-29 21:56:00 +02:00
parent c2a5b4881e
commit 302313916a
7 changed files with 47 additions and 55 deletions

View File

@ -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

View File

@ -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"],

View File

@ -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

View File

@ -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))

View File

@ -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))

View File

@ -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)

View File

@ -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")