created FontManager and restructured __init__.py

This commit is contained in:
Tom Schimansky 2022-05-17 21:44:59 +02:00
parent eec16e4509
commit afe44f4ff7
23 changed files with 436 additions and 430 deletions

View File

@ -1,5 +1,39 @@
__version__ = "3.12"
import os
import sys
# import manager classes
from .settings import Settings
from .appearance_mode_tracker import AppearanceModeTracker
from .theme_manager import ThemeManager
from .scaling_tracker import ScalingTracker
from .font_manager import FontManager
Settings.init_font_character_mapping()
Settings.init_drawing_method()
AppearanceModeTracker.init_appearance_mode()
ThemeManager.load_theme("blue")
FontManager.init_font_manager()
# load Roboto fonts
script_directory = os.path.dirname(os.path.abspath(__file__))
FontManager.load_font(os.path.join(script_directory, "assets", "fonts", "Roboto", "Roboto-Regular.ttf"))
FontManager.load_font(os.path.join(script_directory, "assets", "fonts", "Roboto", "Roboto-Medium.ttf"))
# load font necessary for rendering the widgets on Windows, Linux
if FontManager.load_font(os.path.join(script_directory, "assets", "fonts", "CustomTkinter_shapes_font-fine.otf")) is True:
Settings.circle_font_is_ready = True
if Settings.preferred_drawing_method == "font_shapes":
sys.stderr.write("customtkinter.__init__ warning: " +
"Preferred drawing method 'font_shapes' can not be used because the font file could not be loaded.\n" +
"Using 'circle_shapes' instead. The rendering quality will be bad!")
Settings.preferred_drawing_method = "circle_shapes"
# import widgets
from .widgets.ctk_button import CTkButton
from .widgets.ctk_checkbox import CTkCheckBox
@ -17,16 +51,6 @@ from .windows.ctk_tk import CTk
from .windows.ctk_toplevel import CTkToplevel
from .windows.ctk_input_dialog import CTkInputDialog
# import other classes
from .ctk_settings import CTkSettings
from .appearance_mode_tracker import AppearanceModeTracker
from .ctk_theme_manager import CTkThemeManager
from .scaling_tracker import ScalingTracker
import os
import sys
import shutil
def set_appearance_mode(mode_string):
AppearanceModeTracker.set_appearance_mode(mode_string)
@ -40,77 +64,13 @@ def get_appearance_mode():
def set_default_color_theme(color_string):
CTkThemeManager.load_theme(color_string)
ThemeManager.load_theme(color_string)
def deactivate_dpi_awareness(deactivate_awareness: bool):
CTkSettings.deactivate_automatic_dpi_awareness = deactivate_awareness
Settings.deactivate_automatic_dpi_awareness = deactivate_awareness
def set_user_scaling(scaling_value: float):
ScalingTracker.set_spacing_scaling(scaling_value)
ScalingTracker.set_widget_scaling(scaling_value)
# Load fonts:
if sys.platform.startswith("win"):
from ctypes import windll, byref, create_unicode_buffer, create_string_buffer
FR_PRIVATE = 0x10
FR_NOT_ENUM = 0x20
def loadfont(fontpath, private=True, enumerable=False):
""" Function taken from: https://stackoverflow.com/questions/11993290/truly-custom-font-in-tkinter/30631309#30631309 """
if isinstance(fontpath, bytes):
pathbuf = create_string_buffer(fontpath)
AddFontResourceEx = windll.gdi32.AddFontResourceExA
elif isinstance(fontpath, str):
pathbuf = create_unicode_buffer(fontpath)
AddFontResourceEx = windll.gdi32.AddFontResourceExW
else:
raise TypeError('fontpath must be of type bytes or str')
flags = (FR_PRIVATE if private else 0) | (FR_NOT_ENUM if not enumerable else 0)
num_fonts_added = AddFontResourceEx(byref(pathbuf), flags, 0)
return bool(num_fonts_added)
# load text fonts and custom font with circle shapes for round corner rendering
script_directory = os.path.dirname(os.path.abspath(__file__))
CTkSettings.circle_font_is_ready = loadfont(os.path.join(script_directory, "assets", "fonts", "CustomTkinter_shapes_font-fine.otf"))
loadfont(os.path.join(script_directory, "assets", "fonts", "Roboto", "Roboto-Regular.ttf"))
loadfont(os.path.join(script_directory, "assets", "fonts", "Roboto", "Roboto-Medium.ttf"))
# correct drawing method if font could not be loaded
if not CTkSettings.circle_font_is_ready:
if CTkSettings.preferred_drawing_method == "font_shapes":
sys.stderr.write("WARNING (customtkinter.CTkSettings): " +
"Preferred drawing method 'font_shapes' can not be used because the font file could not be loaded.\n" +
"Using 'circle_shapes' instead. The rendering quality will be very bad!")
CTkSettings.preferred_drawing_method = "circle_shapes"
elif sys.platform.startswith("linux"):
try:
if not os.path.isdir(os.path.expanduser('~/.fonts/')):
os.mkdir(os.path.expanduser('~/.fonts/'))
script_directory = os.path.dirname(os.path.abspath(__file__))
# copy fonts in user font folder
shutil.copy(os.path.join(script_directory, "assets", "fonts", "Roboto", "Roboto-Regular.ttf"),
os.path.expanduser("~/.fonts/"))
shutil.copy(os.path.join(script_directory, "assets", "fonts", "Roboto", "Roboto-Medium.ttf"),
os.path.expanduser("~/.fonts/"))
shutil.copy(os.path.join(script_directory, "assets", "fonts", "CustomTkinter_shapes_font-fine.otf"),
os.path.expanduser("~/.fonts/"))
except Exception as err:
sys.stderr.write(str(err) + "\n")
sys.stderr.write("WARNING (customtkinter.CTkSettings): " +
"Preferred drawing method 'font_shapes' can not be used because the font file could not be copied to ~/.fonts/.\n" +
"Using 'circle_shapes' instead. The rendering quality will be very bad!\n")
CTkSettings.preferred_drawing_method = "circle_shapes"

View File

@ -1,6 +1,7 @@
import sys
import tkinter
from distutils.version import StrictVersion as Version
from typing import Callable
try:
import darkdetect
@ -32,7 +33,7 @@ class AppearanceModeTracker:
cls.update_callbacks()
@classmethod
def add(cls, callback, widget=None):
def add(cls, callback: Callable, widget=None):
cls.callback_list.append(callback)
if widget is not None:
@ -45,11 +46,11 @@ class AppearanceModeTracker:
cls.update_loop_running = True
@classmethod
def remove(cls, callback):
def remove(cls, callback: Callable):
cls.callback_list.remove(callback)
@staticmethod
def detect_appearance_mode():
def detect_appearance_mode() -> int:
try:
if darkdetect.theme() == "Dark":
return 1 # Dark
@ -103,11 +104,11 @@ class AppearanceModeTracker:
cls.update_loop_running = False
@classmethod
def get_mode(cls):
def get_mode(cls) -> int:
return cls.appearance_mode
@classmethod
def set_appearance_mode(cls, mode_string):
def set_appearance_mode(cls, mode_string: str):
if mode_string.lower() == "dark":
cls.appearance_mode_set_by = "user"
new_appearance_mode = 1
@ -126,6 +127,3 @@ class AppearanceModeTracker:
elif mode_string.lower() == "system":
cls.appearance_mode_set_by = "system"
AppearanceModeTracker.init_appearance_mode()

View File

@ -6,7 +6,7 @@ from typing import Union
from .widgets.ctk_canvas import CTkCanvas
class CTkDrawEngine:
class DrawEngine:
"""
This is the core of the CustomTkinter library where all the drawing on the tkinter.Canvas happens.
A year of experimenting and trying out different drawing methods have led to the current state of this

View File

@ -0,0 +1,64 @@
import sys
import os
import shutil
from typing import Union
class FontManager:
@classmethod
def init_font_manager(cls):
# Linux
if sys.platform.startswith("linux"):
try:
if not os.path.isdir(os.path.expanduser('~/.fonts/')):
os.mkdir(os.path.expanduser('~/.fonts/'))
return True
except Exception as err:
sys.stderr.write("FontManager error: " + str(err) + "\n")
return False
# other platforms
else:
return True
@classmethod
def windows_load_font(cls, font_path: Union[str, bytes], private: bool = True, enumerable: bool = False) -> bool:
""" Function taken from: https://stackoverflow.com/questions/11993290/truly-custom-font-in-tkinter/30631309#30631309 """
from ctypes import windll, byref, create_unicode_buffer, create_string_buffer
FR_PRIVATE = 0x10
FR_NOT_ENUM = 0x20
if isinstance(font_path, bytes):
path_buffer = create_string_buffer(font_path)
add_font_resource_ex = windll.gdi32.AddFontResourceExA
elif isinstance(font_path, str):
path_buffer = create_unicode_buffer(font_path)
add_font_resource_ex = windll.gdi32.AddFontResourceExW
else:
raise TypeError('font_path must be of type bytes or str')
flags = (FR_PRIVATE if private else 0) | (FR_NOT_ENUM if not enumerable else 0)
num_fonts_added = add_font_resource_ex(byref(path_buffer), flags, 0)
return bool(num_fonts_added)
@classmethod
def load_font(cls, font_path: str) -> bool:
# Windows
if sys.platform.startswith("win"):
return cls.windows_load_font(font_path, private=True, enumerable=False)
# Linux
elif sys.platform.startswith("win"):
try:
shutil.copy(font_path, os.path.expanduser("~/.fonts/"))
return True
except Exception as err:
sys.stderr.write("FontManager error: " + str(err) + "\n")
return False
# macOS and others
else:
return False

View File

@ -1,13 +1,13 @@
import tkinter
import sys
from typing import Callable, Type
from .ctk_settings import CTkSettings
from .settings import Settings
class ScalingTracker:
window_widgets_dict = {} # contains window objects as keys with list of widget callbacks as elements
window_dpi_scaling_dict = {} # contains window objects as keys and corresponding scaling factors
widget_scaling = 1 # user values which multiply to detected window scaling factor
@ -17,32 +17,32 @@ class ScalingTracker:
update_loop_running = False
@classmethod
def get_widget_scaling(cls, widget):
def get_widget_scaling(cls, widget) -> float:
window_root = cls.get_window_root_of_widget(widget)
return cls.window_dpi_scaling_dict[window_root] * cls.widget_scaling
@classmethod
def get_spacing_scaling(cls, widget):
def get_spacing_scaling(cls, widget) -> float:
window_root = cls.get_window_root_of_widget(widget)
return cls.window_dpi_scaling_dict[window_root] * cls.spacing_scaling
@classmethod
def get_window_scaling(cls, window):
def get_window_scaling(cls, window) -> float:
window_root = cls.get_window_root_of_widget(window)
return cls.window_dpi_scaling_dict[window_root] * cls.window_scaling
@classmethod
def set_widget_scaling(cls, widget_scaling_factor):
def set_widget_scaling(cls, widget_scaling_factor: float):
cls.widget_scaling = max(widget_scaling_factor, 0.4)
cls.update_scaling_callbacks()
@classmethod
def set_spacing_scaling(cls, spacing_scaling_factor):
def set_spacing_scaling(cls, spacing_scaling_factor: float):
cls.spacing_scaling = max(spacing_scaling_factor, 0.4)
cls.update_scaling_callbacks()
@classmethod
def set_window_scaling(cls, window_scaling_factor):
def set_window_scaling(cls, window_scaling_factor: float):
cls.window_scaling = max(window_scaling_factor, 0.4)
cls.update_scaling_callbacks()
@ -60,7 +60,7 @@ class ScalingTracker:
def update_scaling_callbacks(cls):
for window, callback_list in cls.window_widgets_dict.items():
for callback in callback_list:
if not CTkSettings.deactivate_automatic_dpi_awareness:
if not Settings.deactivate_automatic_dpi_awareness:
callback(cls.window_dpi_scaling_dict[window] * cls.widget_scaling,
cls.window_dpi_scaling_dict[window] * cls.spacing_scaling,
cls.window_dpi_scaling_dict[window] * cls.window_scaling)
@ -70,7 +70,7 @@ class ScalingTracker:
cls.window_scaling)
@classmethod
def add_widget(cls, widget_callback, widget):
def add_widget(cls, widget_callback: Callable, widget):
window_root = cls.get_window_root_of_widget(widget)
if window_root not in cls.window_widgets_dict:
@ -115,7 +115,7 @@ class ScalingTracker:
""" make process DPI aware, customtkinter elemets will get scaled automatically,
only gets activated when CTk object is created """
if not CTkSettings.deactivate_automatic_dpi_awareness:
if not Settings.deactivate_automatic_dpi_awareness:
if sys.platform == "darwin":
pass # high DPI scaling works automatically on macOS
@ -128,7 +128,7 @@ class ScalingTracker:
pass # DPI awareness on Linux not implemented
@classmethod
def get_window_dpi_scaling(cls, window):
def get_window_dpi_scaling(cls, window) -> float:
if sys.platform == "darwin":
return 1 # scaling works automatically on macOS

View File

@ -1,12 +1,11 @@
import sys
class CTkSettings:
class Settings:
circle_font_is_ready = False
preferred_drawing_method: str = None # 'polygon_shapes', 'font_shapes', 'circle_shapes'
radius_to_char_fine: dict = None # set in self.init_font_character_mapping()
cursor_manipulation_enabled = True
deactivate_macos_window_header_manipulation = False
deactivate_windows_window_header_manipulation = False
@ -41,15 +40,3 @@ class CTkSettings:
cls.preferred_drawing_method = "polygon_shapes"
else:
cls.preferred_drawing_method = "font_shapes"
@classmethod
def print_settings(cls):
print(f"CTkSettings current values:")
print(f"circle_font_is_ready = {cls.circle_font_is_ready}")
print(f"hand_cursor_enabled = {cls.cursor_manipulation_enabled}")
print(f"preferred_drawing_method = {cls.preferred_drawing_method}")
print(f"radius_to_char_fine = {cls.radius_to_char_fine}")
CTkSettings.init_font_character_mapping()
CTkSettings.init_drawing_method()

View File

@ -3,7 +3,7 @@ import os
import json
class CTkThemeManager:
class ThemeManager:
theme = {} # contains all the theme data
built_in_themes = ["blue", "green", "dark-blue", "sweetkind"]
@ -65,11 +65,11 @@ class CTkThemeManager:
@classmethod
def multiply_hex_color(cls, hex_color: str, factor: float = 1.0) -> str:
try:
rgb_color = CTkThemeManager.hex2rgb(hex_color)
rgb_color = ThemeManager.hex2rgb(hex_color)
dark_rgb_color = (min(255, rgb_color[0] * factor),
min(255, rgb_color[1] * factor),
min(255, rgb_color[2] * factor))
return CTkThemeManager.rgb2hex(dark_rgb_color)
return ThemeManager.rgb2hex(dark_rgb_color)
except Exception as err:
# sys.stderr.write("ERROR (CTkColorManager): failed to darken the following color: " + str(hex_color) + " " + str(err))
return hex_color
@ -78,6 +78,3 @@ class CTkThemeManager:
def set_main_color(cls, main_color, main_color_hover):
cls.MAIN_COLOR = main_color
cls.MAIN_HOVER_COLOR = main_color_hover
CTkThemeManager.load_theme("blue") # standard theme

View File

@ -3,9 +3,9 @@ import sys
import math
from .ctk_canvas import CTkCanvas
from ..ctk_theme_manager import CTkThemeManager
from ..ctk_settings import CTkSettings
from ..ctk_draw_engine import CTkDrawEngine
from ..theme_manager import ThemeManager
from ..settings import Settings
from ..draw_engine import DrawEngine
from .widget_base_class import CTkBaseClass
@ -39,22 +39,22 @@ class CTkButton(CTkBaseClass):
self.configure_basic_grid()
# color variables
self.fg_color = CTkThemeManager.theme["color"]["button"] if fg_color == "default_theme" else fg_color
self.hover_color = CTkThemeManager.theme["color"]["button_hover"] if hover_color == "default_theme" else hover_color
self.border_color = CTkThemeManager.theme["color"]["button_border"] if border_color == "default_theme" else border_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_border"] if border_color == "default_theme" else border_color
# shape
self.corner_radius = CTkThemeManager.theme["shape"]["button_corner_radius"] if corner_radius == "default_theme" else corner_radius
self.border_width = CTkThemeManager.theme["shape"]["button_border_width"] if border_width == "default_theme" else border_width
self.corner_radius = ThemeManager.theme["shape"]["button_corner_radius"] if corner_radius == "default_theme" else corner_radius
self.border_width = ThemeManager.theme["shape"]["button_border_width"] if border_width == "default_theme" else border_width
# text and font and image
self.image = image
self.image_label = None
self.text = text
self.text_label = None
self.text_color = CTkThemeManager.theme["color"]["text"] if text_color == "default_theme" else text_color
self.text_color_disabled = CTkThemeManager.theme["color"]["text_button_disabled"] if text_color_disabled == "default_theme" else text_color_disabled
self.text_font = (CTkThemeManager.theme["text"]["font"], CTkThemeManager.theme["text"]["size"]) if text_font == "default_theme" else text_font
self.text_color = ThemeManager.theme["color"]["text"] if text_color == "default_theme" else text_color
self.text_color_disabled = ThemeManager.theme["color"]["text_button_disabled"] if text_color_disabled == "default_theme" else text_color_disabled
self.text_font = (ThemeManager.theme["text"]["font"], ThemeManager.theme["text"]["size"]) if text_font == "default_theme" else text_font
# callback and hover functionality
self.function = command
@ -69,7 +69,7 @@ class CTkButton(CTkBaseClass):
width=self.apply_widget_scaling(self.desired_width),
height=self.apply_widget_scaling(self.desired_height))
self.canvas.grid(row=0, column=0, rowspan=2, columnspan=2, sticky="nsew")
self.draw_engine = CTkDrawEngine(self.canvas, CTkSettings.preferred_drawing_method)
self.draw_engine = DrawEngine(self.canvas, Settings.preferred_drawing_method)
# event bindings
self.canvas.bind("<Enter>", self.on_enter)
@ -110,22 +110,22 @@ class CTkButton(CTkBaseClass):
if no_color_updates is False or requires_recoloring:
self.canvas.configure(bg=CTkThemeManager.single_color(self.bg_color, self.appearance_mode))
self.canvas.configure(bg=ThemeManager.single_color(self.bg_color, self.appearance_mode))
# set color for the button border parts (outline)
self.canvas.itemconfig("border_parts",
outline=CTkThemeManager.single_color(self.border_color, self.appearance_mode),
fill=CTkThemeManager.single_color(self.border_color, self.appearance_mode))
outline=ThemeManager.single_color(self.border_color, self.appearance_mode),
fill=ThemeManager.single_color(self.border_color, self.appearance_mode))
# set color for inner button parts
if self.fg_color is None:
self.canvas.itemconfig("inner_parts",
outline=CTkThemeManager.single_color(self.bg_color, self.appearance_mode),
fill=CTkThemeManager.single_color(self.bg_color, self.appearance_mode))
outline=ThemeManager.single_color(self.bg_color, self.appearance_mode),
fill=ThemeManager.single_color(self.bg_color, self.appearance_mode))
else:
self.canvas.itemconfig("inner_parts",
outline=CTkThemeManager.single_color(self.fg_color, self.appearance_mode),
fill=CTkThemeManager.single_color(self.fg_color, self.appearance_mode))
outline=ThemeManager.single_color(self.fg_color, self.appearance_mode),
fill=ThemeManager.single_color(self.fg_color, self.appearance_mode))
# create text label if text given
if self.text is not None and self.text != "":
@ -142,17 +142,17 @@ class CTkButton(CTkBaseClass):
if no_color_updates is False:
# set text_label fg color (text color)
self.text_label.configure(fg=CTkThemeManager.single_color(self.text_color, self.appearance_mode))
self.text_label.configure(fg=ThemeManager.single_color(self.text_color, self.appearance_mode))
if self.state == tkinter.DISABLED:
self.text_label.configure(fg=(CTkThemeManager.single_color(self.text_color_disabled, self.appearance_mode)))
self.text_label.configure(fg=(ThemeManager.single_color(self.text_color_disabled, self.appearance_mode)))
else:
self.text_label.configure(fg=CTkThemeManager.single_color(self.text_color, self.appearance_mode))
self.text_label.configure(fg=ThemeManager.single_color(self.text_color, self.appearance_mode))
if self.fg_color is None:
self.text_label.configure(bg=CTkThemeManager.single_color(self.bg_color, self.appearance_mode))
self.text_label.configure(bg=ThemeManager.single_color(self.bg_color, self.appearance_mode))
else:
self.text_label.configure(bg=CTkThemeManager.single_color(self.fg_color, self.appearance_mode))
self.text_label.configure(bg=ThemeManager.single_color(self.fg_color, self.appearance_mode))
self.text_label.configure(text=self.text) # set text
@ -176,9 +176,9 @@ class CTkButton(CTkBaseClass):
if no_color_updates is False:
# set image_label bg color (background color of label)
if self.fg_color is None:
self.image_label.configure(bg=CTkThemeManager.single_color(self.bg_color, self.appearance_mode))
self.image_label.configure(bg=ThemeManager.single_color(self.bg_color, self.appearance_mode))
else:
self.image_label.configure(bg=CTkThemeManager.single_color(self.fg_color, self.appearance_mode))
self.image_label.configure(bg=ThemeManager.single_color(self.fg_color, self.appearance_mode))
self.image_label.configure(image=self.image) # set image
@ -296,17 +296,17 @@ class CTkButton(CTkBaseClass):
self.draw()
def set_cursor(self):
if CTkSettings.cursor_manipulation_enabled:
if Settings.cursor_manipulation_enabled:
if self.state == tkinter.DISABLED:
if sys.platform == "darwin" and self.function is not None and CTkSettings.cursor_manipulation_enabled:
if sys.platform == "darwin" and self.function is not None and Settings.cursor_manipulation_enabled:
self.configure(cursor="arrow")
elif sys.platform.startswith("win") and self.function is not None and CTkSettings.cursor_manipulation_enabled:
elif sys.platform.startswith("win") and self.function is not None and Settings.cursor_manipulation_enabled:
self.configure(cursor="arrow")
elif self.state == tkinter.NORMAL:
if sys.platform == "darwin" and self.function is not None and CTkSettings.cursor_manipulation_enabled:
if sys.platform == "darwin" and self.function is not None and Settings.cursor_manipulation_enabled:
self.configure(cursor="pointinghand")
elif sys.platform.startswith("win") and self.function is not None and CTkSettings.cursor_manipulation_enabled:
elif sys.platform.startswith("win") and self.function is not None and Settings.cursor_manipulation_enabled:
self.configure(cursor="hand2")
def set_text(self, text):
@ -326,16 +326,16 @@ class CTkButton(CTkBaseClass):
# set color of inner button parts to hover color
self.canvas.itemconfig("inner_parts",
outline=CTkThemeManager.single_color(inner_parts_color, self.appearance_mode),
fill=CTkThemeManager.single_color(inner_parts_color, self.appearance_mode))
outline=ThemeManager.single_color(inner_parts_color, self.appearance_mode),
fill=ThemeManager.single_color(inner_parts_color, self.appearance_mode))
# set text_label bg color to button hover color
if self.text_label is not None:
self.text_label.configure(bg=CTkThemeManager.single_color(inner_parts_color, self.appearance_mode))
self.text_label.configure(bg=ThemeManager.single_color(inner_parts_color, self.appearance_mode))
# set image_label bg color to button hover color
if self.image_label is not None:
self.image_label.configure(bg=CTkThemeManager.single_color(inner_parts_color, self.appearance_mode))
self.image_label.configure(bg=ThemeManager.single_color(inner_parts_color, self.appearance_mode))
def on_leave(self, event=0):
self.click_animation_running = False
@ -348,16 +348,16 @@ class CTkButton(CTkBaseClass):
# set color of inner button parts
self.canvas.itemconfig("inner_parts",
outline=CTkThemeManager.single_color(inner_parts_color, self.appearance_mode),
fill=CTkThemeManager.single_color(inner_parts_color, self.appearance_mode))
outline=ThemeManager.single_color(inner_parts_color, self.appearance_mode),
fill=ThemeManager.single_color(inner_parts_color, self.appearance_mode))
# set text_label bg color (label color)
if self.text_label is not None:
self.text_label.configure(bg=CTkThemeManager.single_color(inner_parts_color, self.appearance_mode))
self.text_label.configure(bg=ThemeManager.single_color(inner_parts_color, self.appearance_mode))
# set image_label bg color (image bg color)
if self.image_label is not None:
self.image_label.configure(bg=CTkThemeManager.single_color(inner_parts_color, self.appearance_mode))
self.image_label.configure(bg=ThemeManager.single_color(inner_parts_color, self.appearance_mode))
def click_animation(self):
if self.click_animation_running:

View File

@ -1,10 +1,10 @@
import tkinter
from ..ctk_settings import CTkSettings
from ..settings import Settings
class CTkCanvas(tkinter.Canvas):
radius_to_char_fine = CTkSettings.radius_to_char_fine # dict to map radius to font circle character
radius_to_char_fine = Settings.radius_to_char_fine # dict to map radius to font circle character
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)

View File

@ -2,9 +2,9 @@ import tkinter
import sys
from .ctk_canvas import CTkCanvas
from ..ctk_theme_manager import CTkThemeManager
from ..ctk_settings import CTkSettings
from ..ctk_draw_engine import CTkDrawEngine
from ..theme_manager import ThemeManager
from ..settings import Settings
from ..draw_engine import DrawEngine
from .widget_base_class import CTkBaseClass
@ -38,21 +38,21 @@ class CTkCheckBox(CTkBaseClass):
super().__init__(*args, bg_color=bg_color, width=width, height=height, **kwargs)
# color
self.fg_color = CTkThemeManager.theme["color"]["button"] if fg_color == "default_theme" else fg_color
self.hover_color = CTkThemeManager.theme["color"]["button_hover"] if hover_color == "default_theme" else hover_color
self.border_color = CTkThemeManager.theme["color"]["checkbox_border"] if border_color == "default_theme" else border_color
self.checkmark_color = CTkThemeManager.theme["color"]["checkmark"] if checkmark_color == "default_theme" else checkmark_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"]["checkbox_border"] if border_color == "default_theme" else border_color
self.checkmark_color = ThemeManager.theme["color"]["checkmark"] if checkmark_color == "default_theme" else checkmark_color
# shape
self.corner_radius = CTkThemeManager.theme["shape"]["checkbox_corner_radius"] if corner_radius == "default_theme" else corner_radius
self.border_width = CTkThemeManager.theme["shape"]["checkbox_border_width"] if border_width == "default_theme" else border_width
self.corner_radius = ThemeManager.theme["shape"]["checkbox_corner_radius"] if corner_radius == "default_theme" else corner_radius
self.border_width = ThemeManager.theme["shape"]["checkbox_border_width"] if border_width == "default_theme" else border_width
# text
self.text = text
self.text_label = None
self.text_color = CTkThemeManager.theme["color"]["text"] if text_color == "default_theme" else text_color
self.text_color_disabled = CTkThemeManager.theme["color"]["text_disabled"] if text_color_disabled == "default_theme" else text_color_disabled
self.text_font = (CTkThemeManager.theme["text"]["font"], CTkThemeManager.theme["text"]["size"]) if text_font == "default_theme" else text_font
self.text_color = ThemeManager.theme["color"]["text"] if text_color == "default_theme" else text_color
self.text_color_disabled = ThemeManager.theme["color"]["text_disabled"] if text_color_disabled == "default_theme" else text_color_disabled
self.text_font = (ThemeManager.theme["text"]["font"], ThemeManager.theme["text"]["size"]) if text_font == "default_theme" else text_font
# callback and hover functionality
self.function = command
@ -83,7 +83,7 @@ class CTkCheckBox(CTkBaseClass):
width=self.apply_widget_scaling(self.desired_width),
height=self.apply_widget_scaling(self.desired_height))
self.canvas.grid(row=0, column=0, padx=0, pady=0, columnspan=1, rowspan=1)
self.draw_engine = CTkDrawEngine(self.canvas, CTkSettings.preferred_drawing_method)
self.draw_engine = DrawEngine(self.canvas, Settings.preferred_drawing_method)
if self.hover is True:
self.canvas.bind("<Enter>", self.on_enter)
@ -132,28 +132,28 @@ class CTkCheckBox(CTkBaseClass):
else:
self.canvas.delete("checkmark")
self.bg_canvas.configure(bg=CTkThemeManager.single_color(self.bg_color, self.appearance_mode))
self.canvas.configure(bg=CTkThemeManager.single_color(self.bg_color, self.appearance_mode))
self.bg_canvas.configure(bg=ThemeManager.single_color(self.bg_color, self.appearance_mode))
self.canvas.configure(bg=ThemeManager.single_color(self.bg_color, self.appearance_mode))
if self.check_state is True:
self.canvas.itemconfig("inner_parts",
outline=CTkThemeManager.single_color(self.fg_color, self.appearance_mode),
fill=CTkThemeManager.single_color(self.fg_color, self.appearance_mode))
outline=ThemeManager.single_color(self.fg_color, self.appearance_mode),
fill=ThemeManager.single_color(self.fg_color, self.appearance_mode))
self.canvas.itemconfig("border_parts",
outline=CTkThemeManager.single_color(self.fg_color, self.appearance_mode),
fill=CTkThemeManager.single_color(self.fg_color, self.appearance_mode))
outline=ThemeManager.single_color(self.fg_color, self.appearance_mode),
fill=ThemeManager.single_color(self.fg_color, self.appearance_mode))
if "create_line" in self.canvas.gettags("checkmark"):
self.canvas.itemconfig("checkmark", fill=CTkThemeManager.single_color(self.checkmark_color, self.appearance_mode))
self.canvas.itemconfig("checkmark", fill=ThemeManager.single_color(self.checkmark_color, self.appearance_mode))
else:
self.canvas.itemconfig("checkmark", fill=CTkThemeManager.single_color(self.checkmark_color, self.appearance_mode))
self.canvas.itemconfig("checkmark", fill=ThemeManager.single_color(self.checkmark_color, self.appearance_mode))
else:
self.canvas.itemconfig("inner_parts",
outline=CTkThemeManager.single_color(self.bg_color, self.appearance_mode),
fill=CTkThemeManager.single_color(self.bg_color, self.appearance_mode))
outline=ThemeManager.single_color(self.bg_color, self.appearance_mode),
fill=ThemeManager.single_color(self.bg_color, self.appearance_mode))
self.canvas.itemconfig("border_parts",
outline=CTkThemeManager.single_color(self.border_color, self.appearance_mode),
fill=CTkThemeManager.single_color(self.border_color, self.appearance_mode))
outline=ThemeManager.single_color(self.border_color, self.appearance_mode),
fill=ThemeManager.single_color(self.border_color, self.appearance_mode))
if self.text_label is None:
self.text_label = tkinter.Label(master=self,
@ -165,10 +165,10 @@ class CTkCheckBox(CTkBaseClass):
self.text_label["anchor"] = "w"
if self.state == tkinter.DISABLED:
self.text_label.configure(fg=(CTkThemeManager.single_color(self.text_color_disabled, self.appearance_mode)))
self.text_label.configure(fg=(ThemeManager.single_color(self.text_color_disabled, self.appearance_mode)))
else:
self.text_label.configure(fg=CTkThemeManager.single_color(self.text_color, self.appearance_mode))
self.text_label.configure(bg=CTkThemeManager.single_color(self.bg_color, self.appearance_mode))
self.text_label.configure(fg=ThemeManager.single_color(self.text_color, self.appearance_mode))
self.text_label.configure(bg=ThemeManager.single_color(self.bg_color, self.appearance_mode))
self.set_text(self.text)
@ -240,17 +240,17 @@ class CTkCheckBox(CTkBaseClass):
self.draw()
def set_cursor(self):
if CTkSettings.cursor_manipulation_enabled:
if Settings.cursor_manipulation_enabled:
if self.state == tkinter.DISABLED:
if sys.platform == "darwin" and CTkSettings.cursor_manipulation_enabled:
if sys.platform == "darwin" and Settings.cursor_manipulation_enabled:
self.canvas.configure(cursor="arrow")
elif sys.platform.startswith("win") and CTkSettings.cursor_manipulation_enabled:
elif sys.platform.startswith("win") and Settings.cursor_manipulation_enabled:
self.canvas.configure(cursor="arrow")
elif self.state == tkinter.NORMAL:
if sys.platform == "darwin" and CTkSettings.cursor_manipulation_enabled:
if sys.platform == "darwin" and Settings.cursor_manipulation_enabled:
self.canvas.configure(cursor="pointinghand")
elif sys.platform.startswith("win") and CTkSettings.cursor_manipulation_enabled:
elif sys.platform.startswith("win") and Settings.cursor_manipulation_enabled:
self.canvas.configure(cursor="hand2")
def set_text(self, text):
@ -264,32 +264,32 @@ class CTkCheckBox(CTkBaseClass):
if self.hover is True and self.state == tkinter.NORMAL:
if self.check_state is True:
self.canvas.itemconfig("inner_parts",
fill=CTkThemeManager.single_color(self.hover_color, self.appearance_mode),
outline=CTkThemeManager.single_color(self.hover_color, self.appearance_mode))
fill=ThemeManager.single_color(self.hover_color, self.appearance_mode),
outline=ThemeManager.single_color(self.hover_color, self.appearance_mode))
self.canvas.itemconfig("border_parts",
fill=CTkThemeManager.single_color(self.hover_color, self.appearance_mode),
outline=CTkThemeManager.single_color(self.hover_color, self.appearance_mode))
fill=ThemeManager.single_color(self.hover_color, self.appearance_mode),
outline=ThemeManager.single_color(self.hover_color, self.appearance_mode))
else:
self.canvas.itemconfig("inner_parts",
fill=CTkThemeManager.single_color(self.hover_color, self.appearance_mode),
outline=CTkThemeManager.single_color(self.hover_color, self.appearance_mode))
fill=ThemeManager.single_color(self.hover_color, self.appearance_mode),
outline=ThemeManager.single_color(self.hover_color, self.appearance_mode))
def on_leave(self, event=0):
if self.hover is True:
if self.check_state is True:
self.canvas.itemconfig("inner_parts",
fill=CTkThemeManager.single_color(self.fg_color, self.appearance_mode),
outline=CTkThemeManager.single_color(self.fg_color, self.appearance_mode))
fill=ThemeManager.single_color(self.fg_color, self.appearance_mode),
outline=ThemeManager.single_color(self.fg_color, self.appearance_mode))
self.canvas.itemconfig("border_parts",
fill=CTkThemeManager.single_color(self.fg_color, self.appearance_mode),
outline=CTkThemeManager.single_color(self.fg_color, self.appearance_mode))
fill=ThemeManager.single_color(self.fg_color, self.appearance_mode),
outline=ThemeManager.single_color(self.fg_color, self.appearance_mode))
else:
self.canvas.itemconfig("inner_parts",
fill=CTkThemeManager.single_color(self.bg_color, self.appearance_mode),
outline=CTkThemeManager.single_color(self.bg_color, self.appearance_mode))
fill=ThemeManager.single_color(self.bg_color, self.appearance_mode),
outline=ThemeManager.single_color(self.bg_color, self.appearance_mode))
self.canvas.itemconfig("border_parts",
fill=CTkThemeManager.single_color(self.border_color, self.appearance_mode),
outline=CTkThemeManager.single_color(self.border_color, self.appearance_mode))
fill=ThemeManager.single_color(self.border_color, self.appearance_mode),
outline=ThemeManager.single_color(self.border_color, self.appearance_mode))
def variable_callback(self, var_name, index, mode):
if not self.variable_callback_blocked:

View File

@ -1,9 +1,9 @@
import tkinter
from .ctk_canvas import CTkCanvas
from ..ctk_theme_manager import CTkThemeManager
from ..ctk_settings import CTkSettings
from ..ctk_draw_engine import CTkDrawEngine
from ..theme_manager import ThemeManager
from ..settings import Settings
from ..draw_engine import DrawEngine
from .widget_base_class import CTkBaseClass
@ -32,25 +32,25 @@ class CTkEntry(CTkBaseClass):
self.grid_rowconfigure(0, weight=1)
self.grid_columnconfigure(0, weight=1)
self.fg_color = CTkThemeManager.theme["color"]["entry"] if fg_color == "default_theme" else fg_color
self.text_color = CTkThemeManager.theme["color"]["text"] if text_color == "default_theme" else text_color
self.placeholder_text_color = CTkThemeManager.theme["color"]["entry_placeholder_text"] if placeholder_text_color == "default_theme" else placeholder_text_color
self.text_font = (CTkThemeManager.theme["text"]["font"], CTkThemeManager.theme["text"]["size"]) if text_font == "default_theme" else text_font
self.border_color = CTkThemeManager.theme["color"]["entry_border"] if border_color == "default_theme" else border_color
self.fg_color = ThemeManager.theme["color"]["entry"] if fg_color == "default_theme" else fg_color
self.text_color = ThemeManager.theme["color"]["text"] if text_color == "default_theme" else text_color
self.placeholder_text_color = ThemeManager.theme["color"]["entry_placeholder_text"] if placeholder_text_color == "default_theme" else placeholder_text_color
self.text_font = (ThemeManager.theme["text"]["font"], ThemeManager.theme["text"]["size"]) if text_font == "default_theme" else text_font
self.border_color = ThemeManager.theme["color"]["entry_border"] if border_color == "default_theme" else border_color
self.placeholder_text = placeholder_text
self.placeholder_text_active = False
self.pre_placeholder_arguments = {} # some set arguments of the entry will be changed for placeholder and then set back
self.corner_radius = CTkThemeManager.theme["shape"]["button_corner_radius"] if corner_radius == "default_theme" else corner_radius
self.border_width = CTkThemeManager.theme["shape"]["entry_border_width"] if border_width == "default_theme" else border_width
self.corner_radius = ThemeManager.theme["shape"]["button_corner_radius"] if corner_radius == "default_theme" else corner_radius
self.border_width = ThemeManager.theme["shape"]["entry_border_width"] if border_width == "default_theme" else border_width
self.canvas = CTkCanvas(master=self,
highlightthickness=0,
width=self.apply_widget_scaling(self.current_width),
height=self.apply_widget_scaling(self.current_height))
self.canvas.grid(column=0, row=0, sticky="we")
self.draw_engine = CTkDrawEngine(self.canvas, CTkSettings.preferred_drawing_method)
self.draw_engine = DrawEngine(self.canvas, Settings.preferred_drawing_method)
self.entry = tkinter.Entry(master=self,
bd=0,
@ -83,20 +83,20 @@ class CTkEntry(CTkBaseClass):
if not self.placeholder_text_active and self.entry.get() == "":
self.placeholder_text_active = True
self.pre_placeholder_arguments = {"show": self.entry.cget("show")}
self.entry.config(fg=CTkThemeManager.single_color(self.placeholder_text_color, self.appearance_mode), show="")
self.entry.config(fg=ThemeManager.single_color(self.placeholder_text_color, self.appearance_mode), show="")
self.entry.delete(0, tkinter.END)
self.entry.insert(0, self.placeholder_text)
def clear_placeholder(self, event=None):
if self.placeholder_text_active:
self.placeholder_text_active = False
self.entry.config(fg=CTkThemeManager.single_color(self.text_color, self.appearance_mode))
self.entry.config(fg=ThemeManager.single_color(self.text_color, self.appearance_mode))
self.entry.delete(0, tkinter.END)
for argument, value in self.pre_placeholder_arguments.items():
self.entry[argument] = value
def draw(self, no_color_updates=False):
self.canvas.configure(bg=CTkThemeManager.single_color(self.bg_color, self.appearance_mode))
self.canvas.configure(bg=ThemeManager.single_color(self.bg_color, self.appearance_mode))
requires_recoloring = self.draw_engine.draw_rounded_rect_with_border(self.apply_widget_scaling(self.current_width),
self.apply_widget_scaling(self.current_height),
@ -104,33 +104,33 @@ class CTkEntry(CTkBaseClass):
self.apply_widget_scaling(self.border_width))
if requires_recoloring or no_color_updates is False:
if CTkThemeManager.single_color(self.fg_color, self.appearance_mode) is not None:
if ThemeManager.single_color(self.fg_color, self.appearance_mode) is not None:
self.canvas.itemconfig("inner_parts",
fill=CTkThemeManager.single_color(self.fg_color, self.appearance_mode),
outline=CTkThemeManager.single_color(self.fg_color, self.appearance_mode))
self.entry.configure(bg=CTkThemeManager.single_color(self.fg_color, self.appearance_mode),
disabledbackground=CTkThemeManager.single_color(self.fg_color, self.appearance_mode),
highlightcolor=CTkThemeManager.single_color(self.fg_color, self.appearance_mode),
fg=CTkThemeManager.single_color(self.text_color, self.appearance_mode),
disabledforeground=CTkThemeManager.single_color(self.text_color, self.appearance_mode),
insertbackground=CTkThemeManager.single_color(self.text_color, self.appearance_mode))
fill=ThemeManager.single_color(self.fg_color, self.appearance_mode),
outline=ThemeManager.single_color(self.fg_color, self.appearance_mode))
self.entry.configure(bg=ThemeManager.single_color(self.fg_color, self.appearance_mode),
disabledbackground=ThemeManager.single_color(self.fg_color, self.appearance_mode),
highlightcolor=ThemeManager.single_color(self.fg_color, self.appearance_mode),
fg=ThemeManager.single_color(self.text_color, self.appearance_mode),
disabledforeground=ThemeManager.single_color(self.text_color, self.appearance_mode),
insertbackground=ThemeManager.single_color(self.text_color, self.appearance_mode))
else:
self.canvas.itemconfig("inner_parts",
fill=CTkThemeManager.single_color(self.bg_color, self.appearance_mode),
outline=CTkThemeManager.single_color(self.bg_color, self.appearance_mode))
self.entry.configure(bg=CTkThemeManager.single_color(self.bg_color, self.appearance_mode),
disabledbackground=CTkThemeManager.single_color(self.bg_color, self.appearance_mode),
highlightcolor=CTkThemeManager.single_color(self.bg_color, self.appearance_mode),
fg=CTkThemeManager.single_color(self.text_color, self.appearance_mode),
disabledforeground=CTkThemeManager.single_color(self.text_color, self.appearance_mode),
insertbackground=CTkThemeManager.single_color(self.text_color, self.appearance_mode))
fill=ThemeManager.single_color(self.bg_color, self.appearance_mode),
outline=ThemeManager.single_color(self.bg_color, self.appearance_mode))
self.entry.configure(bg=ThemeManager.single_color(self.bg_color, self.appearance_mode),
disabledbackground=ThemeManager.single_color(self.bg_color, self.appearance_mode),
highlightcolor=ThemeManager.single_color(self.bg_color, self.appearance_mode),
fg=ThemeManager.single_color(self.text_color, self.appearance_mode),
disabledforeground=ThemeManager.single_color(self.text_color, self.appearance_mode),
insertbackground=ThemeManager.single_color(self.text_color, self.appearance_mode))
self.canvas.itemconfig("border_parts",
fill=CTkThemeManager.single_color(self.border_color, self.appearance_mode),
outline=CTkThemeManager.single_color(self.border_color, self.appearance_mode))
fill=ThemeManager.single_color(self.border_color, self.appearance_mode),
outline=ThemeManager.single_color(self.border_color, self.appearance_mode))
if self.placeholder_text_active:
self.entry.config(fg=CTkThemeManager.single_color(self.placeholder_text_color, self.appearance_mode))
self.entry.config(fg=ThemeManager.single_color(self.placeholder_text_color, self.appearance_mode))
def bind(self, *args, **kwargs):
self.entry.bind(*args, **kwargs)

View File

@ -1,9 +1,9 @@
import tkinter
from .ctk_canvas import CTkCanvas
from ..ctk_theme_manager import CTkThemeManager
from ..ctk_settings import CTkSettings
from ..ctk_draw_engine import CTkDrawEngine
from ..theme_manager import ThemeManager
from ..settings import Settings
from ..draw_engine import DrawEngine
from .widget_base_class import CTkBaseClass
@ -22,30 +22,30 @@ class CTkFrame(CTkBaseClass):
super().__init__(*args, bg_color=bg_color, width=width, height=height, **kwargs)
# color
self.border_color = CTkThemeManager.theme["color"]["frame_border"] if border_color == "default_theme" else border_color
self.border_color = ThemeManager.theme["color"]["frame_border"] if border_color == "default_theme" else border_color
if fg_color == "default_theme":
if isinstance(self.master, CTkFrame):
if self.master.fg_color == CTkThemeManager.theme["color"]["frame_low"]:
self.fg_color = CTkThemeManager.theme["color"]["frame_high"]
if self.master.fg_color == ThemeManager.theme["color"]["frame_low"]:
self.fg_color = ThemeManager.theme["color"]["frame_high"]
else:
self.fg_color = CTkThemeManager.theme["color"]["frame_low"]
self.fg_color = ThemeManager.theme["color"]["frame_low"]
else:
self.fg_color = CTkThemeManager.theme["color"]["frame_low"]
self.fg_color = ThemeManager.theme["color"]["frame_low"]
else:
self.fg_color = fg_color
# shape
self.corner_radius = CTkThemeManager.theme["shape"]["frame_corner_radius"] if corner_radius == "default_theme" else corner_radius
self.border_width = CTkThemeManager.theme["shape"]["frame_border_width"] if border_width == "default_theme" else border_width
self.corner_radius = ThemeManager.theme["shape"]["frame_corner_radius"] if corner_radius == "default_theme" else corner_radius
self.border_width = ThemeManager.theme["shape"]["frame_border_width"] if border_width == "default_theme" else border_width
self.canvas = CTkCanvas(master=self,
highlightthickness=0,
width=self.apply_widget_scaling(self.current_width),
height=self.apply_widget_scaling(self.current_height))
self.canvas.place(x=0, y=0, relwidth=1, relheight=1)
self.canvas.configure(bg=CTkThemeManager.single_color(self.bg_color, self.appearance_mode))
self.draw_engine = CTkDrawEngine(self.canvas, CTkSettings.preferred_drawing_method)
self.canvas.configure(bg=ThemeManager.single_color(self.bg_color, self.appearance_mode))
self.draw_engine = DrawEngine(self.canvas, Settings.preferred_drawing_method)
self.bind('<Configure>', self.update_dimensions_event)
@ -78,17 +78,17 @@ class CTkFrame(CTkBaseClass):
if no_color_updates is False or requires_recoloring:
if self.fg_color is None:
self.canvas.itemconfig("inner_parts",
fill=CTkThemeManager.single_color(self.bg_color, self.appearance_mode),
outline=CTkThemeManager.single_color(self.bg_color, self.appearance_mode))
fill=ThemeManager.single_color(self.bg_color, self.appearance_mode),
outline=ThemeManager.single_color(self.bg_color, self.appearance_mode))
else:
self.canvas.itemconfig("inner_parts",
fill=CTkThemeManager.single_color(self.fg_color, self.appearance_mode),
outline=CTkThemeManager.single_color(self.fg_color, self.appearance_mode))
fill=ThemeManager.single_color(self.fg_color, self.appearance_mode),
outline=ThemeManager.single_color(self.fg_color, self.appearance_mode))
self.canvas.itemconfig("border_parts",
fill=CTkThemeManager.single_color(self.border_color, self.appearance_mode),
outline=CTkThemeManager.single_color(self.border_color, self.appearance_mode))
self.canvas.configure(bg=CTkThemeManager.single_color(self.bg_color, self.appearance_mode))
fill=ThemeManager.single_color(self.border_color, self.appearance_mode),
outline=ThemeManager.single_color(self.border_color, self.appearance_mode))
self.canvas.configure(bg=ThemeManager.single_color(self.bg_color, self.appearance_mode))
self.canvas.tag_lower("inner_parts")
self.canvas.tag_lower("border_parts")

View File

@ -1,9 +1,9 @@
import tkinter
from .ctk_canvas import CTkCanvas
from ..ctk_theme_manager import CTkThemeManager
from ..ctk_settings import CTkSettings
from ..ctk_draw_engine import CTkDrawEngine
from ..theme_manager import ThemeManager
from ..settings import Settings
from ..draw_engine import DrawEngine
from .widget_base_class import CTkBaseClass
@ -27,17 +27,17 @@ class CTkLabel(CTkBaseClass):
super().__init__(*args, bg_color=bg_color, width=width, height=height)
# color
self.fg_color = CTkThemeManager.theme["color"]["label"] if fg_color == "default_theme" else fg_color
self.fg_color = ThemeManager.theme["color"]["label"] if fg_color == "default_theme" else fg_color
if self.fg_color is None:
self.fg_color = self.bg_color
self.text_color = CTkThemeManager.theme["color"]["text"] if text_color == "default_theme" else text_color
self.text_color = ThemeManager.theme["color"]["text"] if text_color == "default_theme" else text_color
# shape
self.corner_radius = CTkThemeManager.theme["shape"]["label_corner_radius"] if corner_radius == "default_theme" else corner_radius
self.corner_radius = ThemeManager.theme["shape"]["label_corner_radius"] if corner_radius == "default_theme" else corner_radius
# text
self.text = text
self.text_font = (CTkThemeManager.theme["text"]["font"], CTkThemeManager.theme["text"]["size"]) if text_font == "default_theme" else text_font
self.text_font = (ThemeManager.theme["text"]["font"], ThemeManager.theme["text"]["size"]) if text_font == "default_theme" else text_font
# configure grid system (1x1)
self.grid_rowconfigure(0, weight=1)
@ -48,7 +48,7 @@ class CTkLabel(CTkBaseClass):
width=self.apply_widget_scaling(self.desired_width),
height=self.apply_widget_scaling(self.desired_height))
self.canvas.grid(row=0, column=0, sticky="nswe")
self.draw_engine = CTkDrawEngine(self.canvas, CTkSettings.preferred_drawing_method)
self.draw_engine = DrawEngine(self.canvas, Settings.preferred_drawing_method)
self.text_label = tkinter.Label(master=self,
highlightthickness=0,
@ -75,22 +75,22 @@ class CTkLabel(CTkBaseClass):
0)
if no_color_updates is False or requires_recoloring:
if CTkThemeManager.single_color(self.fg_color, self.appearance_mode) is not None:
if ThemeManager.single_color(self.fg_color, self.appearance_mode) is not None:
self.canvas.itemconfig("inner_parts",
fill=CTkThemeManager.single_color(self.fg_color, self.appearance_mode),
outline=CTkThemeManager.single_color(self.fg_color, self.appearance_mode))
fill=ThemeManager.single_color(self.fg_color, self.appearance_mode),
outline=ThemeManager.single_color(self.fg_color, self.appearance_mode))
self.text_label.configure(fg=CTkThemeManager.single_color(self.text_color, self.appearance_mode),
bg=CTkThemeManager.single_color(self.fg_color, self.appearance_mode))
self.text_label.configure(fg=ThemeManager.single_color(self.text_color, self.appearance_mode),
bg=ThemeManager.single_color(self.fg_color, self.appearance_mode))
else:
self.canvas.itemconfig("inner_parts",
fill=CTkThemeManager.single_color(self.bg_color, self.appearance_mode),
outline=CTkThemeManager.single_color(self.bg_color, self.appearance_mode))
fill=ThemeManager.single_color(self.bg_color, self.appearance_mode),
outline=ThemeManager.single_color(self.bg_color, self.appearance_mode))
self.text_label.configure(fg=CTkThemeManager.single_color(self.text_color, self.appearance_mode),
bg=CTkThemeManager.single_color(self.bg_color, self.appearance_mode))
self.text_label.configure(fg=ThemeManager.single_color(self.text_color, self.appearance_mode),
bg=ThemeManager.single_color(self.bg_color, self.appearance_mode))
self.canvas.configure(bg=CTkThemeManager.single_color(self.bg_color, self.appearance_mode))
self.canvas.configure(bg=ThemeManager.single_color(self.bg_color, self.appearance_mode))
def configure(self, *args, **kwargs):
require_redraw = False # some attribute changes require a call of self.draw() at the end

View File

@ -1,9 +1,9 @@
import tkinter
from .ctk_canvas import CTkCanvas
from ..ctk_theme_manager import CTkThemeManager
from ..ctk_draw_engine import CTkDrawEngine
from ..ctk_settings import CTkSettings
from ..theme_manager import ThemeManager
from ..draw_engine import DrawEngine
from ..settings import Settings
from .widget_base_class import CTkBaseClass
@ -39,9 +39,9 @@ class CTkProgressBar(CTkBaseClass):
super().__init__(*args, bg_color=bg_color, width=width, height=height, **kwargs)
# color
self.border_color = CTkThemeManager.theme["color"]["progressbar_border"] if border_color == "default_theme" else border_color
self.fg_color = CTkThemeManager.theme["color"]["progressbar"] if fg_color == "default_theme" else fg_color
self.progress_color = CTkThemeManager.theme["color"]["progressbar_progress"] if progress_color == "default_theme" else progress_color
self.border_color = ThemeManager.theme["color"]["progressbar_border"] if border_color == "default_theme" else border_color
self.fg_color = ThemeManager.theme["color"]["progressbar"] if fg_color == "default_theme" else fg_color
self.progress_color = ThemeManager.theme["color"]["progressbar_progress"] if progress_color == "default_theme" else progress_color
# control variable
self.variable = variable
@ -49,8 +49,8 @@ class CTkProgressBar(CTkBaseClass):
self.variable_callback_name = None
# shape
self.corner_radius = CTkThemeManager.theme["shape"]["progressbar_corner_radius"] if corner_radius == "default_theme" else corner_radius
self.border_width = CTkThemeManager.theme["shape"]["progressbar_border_width"] if border_width == "default_theme" else border_width
self.corner_radius = ThemeManager.theme["shape"]["progressbar_corner_radius"] if corner_radius == "default_theme" else corner_radius
self.border_width = ThemeManager.theme["shape"]["progressbar_border_width"] if border_width == "default_theme" else border_width
self.value = 0.5
self.orient = orient
@ -62,7 +62,7 @@ class CTkProgressBar(CTkBaseClass):
width=self.apply_widget_scaling(self.desired_width),
height=self.apply_widget_scaling(self.desired_height))
self.canvas.grid(row=0, column=0, rowspan=1, columnspan=1, sticky="nswe")
self.draw_engine = CTkDrawEngine(self.canvas, CTkSettings.preferred_drawing_method)
self.draw_engine = DrawEngine(self.canvas, Settings.preferred_drawing_method)
# Each time an item is resized due to pack position mode, the binding Configure is called on the widget
self.bind('<Configure>', self.update_dimensions_event)
@ -103,16 +103,16 @@ class CTkProgressBar(CTkBaseClass):
orientation)
if no_color_updates is False or requires_recoloring:
self.canvas.configure(bg=CTkThemeManager.single_color(self.bg_color, self.appearance_mode))
self.canvas.configure(bg=ThemeManager.single_color(self.bg_color, self.appearance_mode))
self.canvas.itemconfig("border_parts",
fill=CTkThemeManager.single_color(self.border_color, self.appearance_mode),
outline=CTkThemeManager.single_color(self.border_color, self.appearance_mode))
fill=ThemeManager.single_color(self.border_color, self.appearance_mode),
outline=ThemeManager.single_color(self.border_color, self.appearance_mode))
self.canvas.itemconfig("inner_parts",
fill=CTkThemeManager.single_color(self.fg_color, self.appearance_mode),
outline=CTkThemeManager.single_color(self.fg_color, self.appearance_mode))
fill=ThemeManager.single_color(self.fg_color, self.appearance_mode),
outline=ThemeManager.single_color(self.fg_color, self.appearance_mode))
self.canvas.itemconfig("progress_parts",
fill=CTkThemeManager.single_color(self.progress_color, self.appearance_mode),
outline=CTkThemeManager.single_color(self.progress_color, self.appearance_mode))
fill=ThemeManager.single_color(self.progress_color, self.appearance_mode),
outline=ThemeManager.single_color(self.progress_color, self.appearance_mode))
def configure(self, *args, **kwargs):
require_redraw = False # some attribute changes require a call of self.draw() at the end

View File

@ -2,9 +2,9 @@ import tkinter
import sys
from .ctk_canvas import CTkCanvas
from ..ctk_theme_manager import CTkThemeManager
from ..ctk_settings import CTkSettings
from ..ctk_draw_engine import CTkDrawEngine
from ..theme_manager import ThemeManager
from ..settings import Settings
from ..draw_engine import DrawEngine
from .widget_base_class import CTkBaseClass
@ -35,22 +35,22 @@ class CTkRadioButton(CTkBaseClass):
super().__init__(*args, bg_color=bg_color, width=width, height=height, **kwargs)
# color
self.fg_color = CTkThemeManager.theme["color"]["button"] if fg_color == "default_theme" else fg_color
self.hover_color = CTkThemeManager.theme["color"]["button_hover"] if hover_color == "default_theme" else hover_color
self.border_color = CTkThemeManager.theme["color"]["checkbox_border"] if border_color == "default_theme" else border_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"]["checkbox_border"] if border_color == "default_theme" else border_color
# shape
self.corner_radius = CTkThemeManager.theme["shape"]["radiobutton_corner_radius"] if corner_radius == "default_theme" else corner_radius
self.border_width_unchecked = CTkThemeManager.theme["shape"]["radiobutton_border_width_unchecked"] if border_width_unchecked == "default_theme" else border_width_unchecked
self.border_width_checked = CTkThemeManager.theme["shape"]["radiobutton_border_width_checked"] if border_width_checked == "default_theme" else border_width_checked
self.corner_radius = ThemeManager.theme["shape"]["radiobutton_corner_radius"] if corner_radius == "default_theme" else corner_radius
self.border_width_unchecked = ThemeManager.theme["shape"]["radiobutton_border_width_unchecked"] if border_width_unchecked == "default_theme" else border_width_unchecked
self.border_width_checked = ThemeManager.theme["shape"]["radiobutton_border_width_checked"] if border_width_checked == "default_theme" else border_width_checked
self.border_width = self.border_width_unchecked
# text
self.text = text
self.text_label = None
self.text_color = CTkThemeManager.theme["color"]["text"] if text_color == "default_theme" else text_color
self.text_color_disabled = CTkThemeManager.theme["color"]["text_disabled"] if text_color_disabled == "default_theme" else text_color_disabled
self.text_font = (CTkThemeManager.theme["text"]["font"], CTkThemeManager.theme["text"]["size"]) if text_font == "default_theme" else text_font
self.text_color = ThemeManager.theme["color"]["text"] if text_color == "default_theme" else text_color
self.text_color_disabled = ThemeManager.theme["color"]["text_disabled"] if text_color_disabled == "default_theme" else text_color_disabled
self.text_font = (ThemeManager.theme["text"]["font"], ThemeManager.theme["text"]["size"]) if text_font == "default_theme" else text_font
# callback and control variables
self.function = command
@ -79,7 +79,7 @@ class CTkRadioButton(CTkBaseClass):
width=self.apply_widget_scaling(self.current_width),
height=self.apply_widget_scaling(self.current_height))
self.canvas.grid(row=0, column=0, padx=0, pady=0, columnspan=1)
self.draw_engine = CTkDrawEngine(self.canvas, CTkSettings.preferred_drawing_method)
self.draw_engine = DrawEngine(self.canvas, Settings.preferred_drawing_method)
self.canvas.bind("<Enter>", self.on_enter)
self.canvas.bind("<Leave>", self.on_leave)
@ -118,21 +118,21 @@ class CTkRadioButton(CTkBaseClass):
self.apply_widget_scaling(self.corner_radius),
self.apply_widget_scaling(self.border_width))
self.bg_canvas.configure(bg=CTkThemeManager.single_color(self.bg_color, self.appearance_mode))
self.canvas.configure(bg=CTkThemeManager.single_color(self.bg_color, self.appearance_mode))
self.bg_canvas.configure(bg=ThemeManager.single_color(self.bg_color, self.appearance_mode))
self.canvas.configure(bg=ThemeManager.single_color(self.bg_color, self.appearance_mode))
if self.check_state is False:
self.canvas.itemconfig("border_parts",
outline=CTkThemeManager.single_color(self.border_color, self.appearance_mode),
fill=CTkThemeManager.single_color(self.border_color, self.appearance_mode))
outline=ThemeManager.single_color(self.border_color, self.appearance_mode),
fill=ThemeManager.single_color(self.border_color, self.appearance_mode))
else:
self.canvas.itemconfig("border_parts",
outline=CTkThemeManager.single_color(self.fg_color, self.appearance_mode),
fill=CTkThemeManager.single_color(self.fg_color, self.appearance_mode))
outline=ThemeManager.single_color(self.fg_color, self.appearance_mode),
fill=ThemeManager.single_color(self.fg_color, self.appearance_mode))
self.canvas.itemconfig("inner_parts",
outline=CTkThemeManager.single_color(self.bg_color, self.appearance_mode),
fill=CTkThemeManager.single_color(self.bg_color, self.appearance_mode))
outline=ThemeManager.single_color(self.bg_color, self.appearance_mode),
fill=ThemeManager.single_color(self.bg_color, self.appearance_mode))
if self.text_label is None:
self.text_label = tkinter.Label(master=self,
@ -144,11 +144,11 @@ class CTkRadioButton(CTkBaseClass):
self.text_label["anchor"] = "w"
if self.state == tkinter.DISABLED:
self.text_label.configure(fg=CTkThemeManager.single_color(self.text_color_disabled, self.appearance_mode))
self.text_label.configure(fg=ThemeManager.single_color(self.text_color_disabled, self.appearance_mode))
else:
self.text_label.configure(fg=CTkThemeManager.single_color(self.text_color, self.appearance_mode))
self.text_label.configure(fg=ThemeManager.single_color(self.text_color, self.appearance_mode))
self.text_label.configure(bg=CTkThemeManager.single_color(self.bg_color, self.appearance_mode))
self.text_label.configure(bg=ThemeManager.single_color(self.bg_color, self.appearance_mode))
self.set_text(self.text)
@ -225,17 +225,17 @@ class CTkRadioButton(CTkBaseClass):
self.draw()
def set_cursor(self):
if CTkSettings.cursor_manipulation_enabled:
if Settings.cursor_manipulation_enabled:
if self.state == tkinter.DISABLED:
if sys.platform == "darwin" and CTkSettings.cursor_manipulation_enabled:
if sys.platform == "darwin" and Settings.cursor_manipulation_enabled:
self.canvas.configure(cursor="arrow")
elif sys.platform.startswith("win") and CTkSettings.cursor_manipulation_enabled:
elif sys.platform.startswith("win") and Settings.cursor_manipulation_enabled:
self.canvas.configure(cursor="arrow")
elif self.state == tkinter.NORMAL:
if sys.platform == "darwin" and CTkSettings.cursor_manipulation_enabled:
if sys.platform == "darwin" and Settings.cursor_manipulation_enabled:
self.canvas.configure(cursor="pointinghand")
elif sys.platform.startswith("win") and CTkSettings.cursor_manipulation_enabled:
elif sys.platform.startswith("win") and Settings.cursor_manipulation_enabled:
self.canvas.configure(cursor="hand2")
def set_text(self, text):
@ -248,19 +248,19 @@ class CTkRadioButton(CTkBaseClass):
def on_enter(self, event=0):
if self.hover is True and self.state == tkinter.NORMAL:
self.canvas.itemconfig("border_parts",
fill=CTkThemeManager.single_color(self.hover_color, self.appearance_mode),
outline=CTkThemeManager.single_color(self.hover_color, self.appearance_mode))
fill=ThemeManager.single_color(self.hover_color, self.appearance_mode),
outline=ThemeManager.single_color(self.hover_color, self.appearance_mode))
def on_leave(self, event=0):
if self.hover is True:
if self.check_state is True:
self.canvas.itemconfig("border_parts",
fill=CTkThemeManager.single_color(self.fg_color, self.appearance_mode),
outline=CTkThemeManager.single_color(self.fg_color, self.appearance_mode))
fill=ThemeManager.single_color(self.fg_color, self.appearance_mode),
outline=ThemeManager.single_color(self.fg_color, self.appearance_mode))
else:
self.canvas.itemconfig("border_parts",
fill=CTkThemeManager.single_color(self.border_color, self.appearance_mode),
outline=CTkThemeManager.single_color(self.border_color, self.appearance_mode))
fill=ThemeManager.single_color(self.border_color, self.appearance_mode),
outline=ThemeManager.single_color(self.border_color, self.appearance_mode))
def variable_callback(self, var_name, index, mode):
if not self.variable_callback_blocked:

View File

@ -2,9 +2,9 @@ import tkinter
import sys
from .ctk_canvas import CTkCanvas
from ..ctk_theme_manager import CTkThemeManager
from ..ctk_settings import CTkSettings
from ..ctk_draw_engine import CTkDrawEngine
from ..theme_manager import ThemeManager
from ..settings import Settings
from ..draw_engine import DrawEngine
from .widget_base_class import CTkBaseClass
@ -49,16 +49,16 @@ class CTkSlider(CTkBaseClass):
# color
self.border_color = border_color
self.fg_color = CTkThemeManager.theme["color"]["slider"] if fg_color == "default_theme" else fg_color
self.progress_color = CTkThemeManager.theme["color"]["slider_progress"] if progress_color == "default_theme" else progress_color
self.button_color = CTkThemeManager.theme["color"]["slider_button"] if button_color == "default_theme" else button_color
self.button_hover_color = CTkThemeManager.theme["color"]["slider_button_hover"] if button_hover_color == "default_theme" else button_hover_color
self.fg_color = ThemeManager.theme["color"]["slider"] if fg_color == "default_theme" else fg_color
self.progress_color = ThemeManager.theme["color"]["slider_progress"] if progress_color == "default_theme" else progress_color
self.button_color = ThemeManager.theme["color"]["slider_button"] if button_color == "default_theme" else button_color
self.button_hover_color = ThemeManager.theme["color"]["slider_button_hover"] if button_hover_color == "default_theme" else button_hover_color
# shape
self.corner_radius = CTkThemeManager.theme["shape"]["slider_corner_radius"] if corner_radius == "default_theme" else corner_radius
self.button_corner_radius = CTkThemeManager.theme["shape"]["slider_button_corner_radius"] if button_corner_radius == "default_theme" else button_corner_radius
self.border_width = CTkThemeManager.theme["shape"]["slider_border_width"] if border_width == "default_theme" else border_width
self.button_length = CTkThemeManager.theme["shape"]["slider_button_length"] if button_length == "default_theme" else button_length
self.corner_radius = ThemeManager.theme["shape"]["slider_corner_radius"] if corner_radius == "default_theme" else corner_radius
self.button_corner_radius = ThemeManager.theme["shape"]["slider_button_corner_radius"] if button_corner_radius == "default_theme" else button_corner_radius
self.border_width = ThemeManager.theme["shape"]["slider_border_width"] if border_width == "default_theme" else border_width
self.button_length = ThemeManager.theme["shape"]["slider_button_length"] if button_length == "default_theme" else button_length
self.value = 0.5 # initial value of slider in percent
self.orient = orient
self.hover_state = False
@ -84,7 +84,7 @@ class CTkSlider(CTkBaseClass):
width=self.apply_widget_scaling(self.desired_width),
height=self.apply_widget_scaling(self.desired_height))
self.canvas.grid(column=0, row=0, rowspan=1, columnspan=1, sticky="nswe")
self.draw_engine = CTkDrawEngine(self.canvas, CTkSettings.preferred_drawing_method)
self.draw_engine = DrawEngine(self.canvas, Settings.preferred_drawing_method)
self.canvas.bind("<Enter>", self.on_enter)
self.canvas.bind("<Leave>", self.on_leave)
@ -117,7 +117,7 @@ class CTkSlider(CTkBaseClass):
super().destroy()
def set_cursor(self):
if CTkSettings.cursor_manipulation_enabled:
if Settings.cursor_manipulation_enabled:
if sys.platform == "darwin":
self.configure(cursor="pointinghand")
elif sys.platform.startswith("win"):
@ -140,27 +140,27 @@ class CTkSlider(CTkBaseClass):
self.value, orientation)
if no_color_updates is False or requires_recoloring:
self.canvas.configure(bg=CTkThemeManager.single_color(self.bg_color, self.appearance_mode))
self.canvas.configure(bg=ThemeManager.single_color(self.bg_color, self.appearance_mode))
if self.border_color is None:
self.canvas.itemconfig("border_parts", fill=CTkThemeManager.single_color(self.bg_color, self.appearance_mode),
outline=CTkThemeManager.single_color(self.bg_color, self.appearance_mode))
self.canvas.itemconfig("border_parts", fill=ThemeManager.single_color(self.bg_color, self.appearance_mode),
outline=ThemeManager.single_color(self.bg_color, self.appearance_mode))
else:
self.canvas.itemconfig("border_parts", fill=CTkThemeManager.single_color(self.border_color, self.appearance_mode),
outline=CTkThemeManager.single_color(self.border_color, self.appearance_mode))
self.canvas.itemconfig("border_parts", fill=ThemeManager.single_color(self.border_color, self.appearance_mode),
outline=ThemeManager.single_color(self.border_color, self.appearance_mode))
self.canvas.itemconfig("inner_parts", fill=CTkThemeManager.single_color(self.fg_color, self.appearance_mode),
outline=CTkThemeManager.single_color(self.fg_color, self.appearance_mode))
self.canvas.itemconfig("inner_parts", fill=ThemeManager.single_color(self.fg_color, self.appearance_mode),
outline=ThemeManager.single_color(self.fg_color, self.appearance_mode))
if self.progress_color is None:
self.canvas.itemconfig("progress_parts", fill=CTkThemeManager.single_color(self.fg_color, self.appearance_mode),
outline=CTkThemeManager.single_color(self.fg_color, self.appearance_mode))
self.canvas.itemconfig("progress_parts", fill=ThemeManager.single_color(self.fg_color, self.appearance_mode),
outline=ThemeManager.single_color(self.fg_color, self.appearance_mode))
else:
self.canvas.itemconfig("progress_parts", fill=CTkThemeManager.single_color(self.progress_color, self.appearance_mode),
outline=CTkThemeManager.single_color(self.progress_color, self.appearance_mode))
self.canvas.itemconfig("progress_parts", fill=ThemeManager.single_color(self.progress_color, self.appearance_mode),
outline=ThemeManager.single_color(self.progress_color, self.appearance_mode))
self.canvas.itemconfig("slider_parts", fill=CTkThemeManager.single_color(self.button_color, self.appearance_mode),
outline=CTkThemeManager.single_color(self.button_color, self.appearance_mode))
self.canvas.itemconfig("slider_parts", fill=ThemeManager.single_color(self.button_color, self.appearance_mode),
outline=ThemeManager.single_color(self.button_color, self.appearance_mode))
def clicked(self, event=None):
if self.orient.lower() == "horizontal":
@ -188,13 +188,13 @@ class CTkSlider(CTkBaseClass):
def on_enter(self, event=0):
self.hover_state = True
self.canvas.itemconfig("slider_parts", fill=CTkThemeManager.single_color(self.button_hover_color, self.appearance_mode),
outline=CTkThemeManager.single_color(self.button_hover_color, self.appearance_mode))
self.canvas.itemconfig("slider_parts", fill=ThemeManager.single_color(self.button_hover_color, self.appearance_mode),
outline=ThemeManager.single_color(self.button_hover_color, self.appearance_mode))
def on_leave(self, event=0):
self.hover_state = False
self.canvas.itemconfig("slider_parts", fill=CTkThemeManager.single_color(self.button_color, self.appearance_mode),
outline=CTkThemeManager.single_color(self.button_color, self.appearance_mode))
self.canvas.itemconfig("slider_parts", fill=ThemeManager.single_color(self.button_color, self.appearance_mode),
outline=ThemeManager.single_color(self.button_color, self.appearance_mode))
def round_to_step_size(self, value):
if self.number_of_steps is not None:

View File

@ -2,9 +2,9 @@ import tkinter
import sys
from .ctk_canvas import CTkCanvas
from ..ctk_theme_manager import CTkThemeManager
from ..ctk_settings import CTkSettings
from ..ctk_draw_engine import CTkDrawEngine
from ..theme_manager import ThemeManager
from ..settings import Settings
from ..draw_engine import DrawEngine
from .widget_base_class import CTkBaseClass
@ -37,22 +37,22 @@ class CTkSwitch(CTkBaseClass):
# color
self.border_color = border_color
self.fg_color = CTkThemeManager.theme["color"]["switch"] if fg_color == "default_theme" else fg_color
self.progress_color = CTkThemeManager.theme["color"]["switch_progress"] if progress_color == "default_theme" else progress_color
self.button_color = CTkThemeManager.theme["color"]["switch_button"] if button_color == "default_theme" else button_color
self.button_hover_color = CTkThemeManager.theme["color"]["switch_button_hover"] if button_hover_color == "default_theme" else button_hover_color
self.text_color = CTkThemeManager.theme["color"]["text"] if text_color == "default_theme" else text_color
self.fg_color = ThemeManager.theme["color"]["switch"] if fg_color == "default_theme" else fg_color
self.progress_color = ThemeManager.theme["color"]["switch_progress"] if progress_color == "default_theme" else progress_color
self.button_color = ThemeManager.theme["color"]["switch_button"] if button_color == "default_theme" else button_color
self.button_hover_color = ThemeManager.theme["color"]["switch_button_hover"] if button_hover_color == "default_theme" else button_hover_color
self.text_color = ThemeManager.theme["color"]["text"] if text_color == "default_theme" else text_color
# text
self.text = text
self.text_label = None
self.text_font = (CTkThemeManager.theme["text"]["font"], CTkThemeManager.theme["text"]["size"]) if text_font == "default_theme" else text_font
self.text_font = (ThemeManager.theme["text"]["font"], ThemeManager.theme["text"]["size"]) if text_font == "default_theme" else text_font
# shape
self.corner_radius = CTkThemeManager.theme["shape"]["switch_corner_radius"] if corner_radius == "default_theme" else corner_radius
# self.button_corner_radius = CTkThemeManager.theme["shape"]["switch_button_corner_radius"] if button_corner_radius == "default_theme" else button_corner_radius
self.border_width = CTkThemeManager.theme["shape"]["switch_border_width"] if border_width == "default_theme" else border_width
self.button_length = CTkThemeManager.theme["shape"]["switch_button_length"] if button_length == "default_theme" else button_length
self.corner_radius = ThemeManager.theme["shape"]["switch_corner_radius"] if corner_radius == "default_theme" else corner_radius
# self.button_corner_radius = ThemeManager.theme["shape"]["switch_button_corner_radius"] if button_corner_radius == "default_theme" else button_corner_radius
self.border_width = ThemeManager.theme["shape"]["switch_border_width"] if border_width == "default_theme" else border_width
self.button_length = ThemeManager.theme["shape"]["switch_button_length"] if button_length == "default_theme" else button_length
self.hover_state = False
self.check_state = False # True if switch is activated
self.onvalue = onvalue
@ -84,7 +84,7 @@ class CTkSwitch(CTkBaseClass):
width=self.apply_widget_scaling(self.current_width),
height=self.apply_widget_scaling(self.current_height))
self.canvas.grid(row=0, column=0, padx=0, pady=0, columnspan=1, sticky="nswe")
self.draw_engine = CTkDrawEngine(self.canvas, CTkSettings.preferred_drawing_method)
self.draw_engine = DrawEngine(self.canvas, Settings.preferred_drawing_method)
self.canvas.bind("<Enter>", self.on_enter)
self.canvas.bind("<Leave>", self.on_leave)
@ -118,10 +118,10 @@ class CTkSwitch(CTkBaseClass):
super().destroy()
def set_cursor(self):
if CTkSettings.cursor_manipulation_enabled:
if sys.platform == "darwin" and CTkSettings.cursor_manipulation_enabled:
if Settings.cursor_manipulation_enabled:
if sys.platform == "darwin" and Settings.cursor_manipulation_enabled:
self.canvas.configure(cursor="pointinghand")
elif sys.platform.startswith("win") and CTkSettings.cursor_manipulation_enabled:
elif sys.platform.startswith("win") and Settings.cursor_manipulation_enabled:
self.canvas.configure(cursor="hand2")
def draw(self, no_color_updates=False):
@ -144,28 +144,28 @@ class CTkSwitch(CTkBaseClass):
0, "w")
if no_color_updates is False or requires_recoloring:
self.bg_canvas.configure(bg=CTkThemeManager.single_color(self.bg_color, self.appearance_mode))
self.canvas.configure(bg=CTkThemeManager.single_color(self.bg_color, self.appearance_mode))
self.bg_canvas.configure(bg=ThemeManager.single_color(self.bg_color, self.appearance_mode))
self.canvas.configure(bg=ThemeManager.single_color(self.bg_color, self.appearance_mode))
if self.border_color is None:
self.canvas.itemconfig("border_parts", fill=CTkThemeManager.single_color(self.bg_color, self.appearance_mode),
outline=CTkThemeManager.single_color(self.bg_color, self.appearance_mode))
self.canvas.itemconfig("border_parts", fill=ThemeManager.single_color(self.bg_color, self.appearance_mode),
outline=ThemeManager.single_color(self.bg_color, self.appearance_mode))
else:
self.canvas.itemconfig("border_parts", fill=CTkThemeManager.single_color(self.border_color, self.appearance_mode),
outline=CTkThemeManager.single_color(self.border_color, self.appearance_mode))
self.canvas.itemconfig("border_parts", fill=ThemeManager.single_color(self.border_color, self.appearance_mode),
outline=ThemeManager.single_color(self.border_color, self.appearance_mode))
self.canvas.itemconfig("inner_parts", fill=CTkThemeManager.single_color(self.fg_color, self.appearance_mode),
outline=CTkThemeManager.single_color(self.fg_color, self.appearance_mode))
self.canvas.itemconfig("inner_parts", fill=ThemeManager.single_color(self.fg_color, self.appearance_mode),
outline=ThemeManager.single_color(self.fg_color, self.appearance_mode))
if self.progress_color is None:
self.canvas.itemconfig("progress_parts", fill=CTkThemeManager.single_color(self.fg_color, self.appearance_mode),
outline=CTkThemeManager.single_color(self.fg_color, self.appearance_mode))
self.canvas.itemconfig("progress_parts", fill=ThemeManager.single_color(self.fg_color, self.appearance_mode),
outline=ThemeManager.single_color(self.fg_color, self.appearance_mode))
else:
self.canvas.itemconfig("progress_parts", fill=CTkThemeManager.single_color(self.progress_color, self.appearance_mode),
outline=CTkThemeManager.single_color(self.progress_color, self.appearance_mode))
self.canvas.itemconfig("progress_parts", fill=ThemeManager.single_color(self.progress_color, self.appearance_mode),
outline=ThemeManager.single_color(self.progress_color, self.appearance_mode))
self.canvas.itemconfig("slider_parts", fill=CTkThemeManager.single_color(self.button_color, self.appearance_mode),
outline=CTkThemeManager.single_color(self.button_color, self.appearance_mode))
self.canvas.itemconfig("slider_parts", fill=ThemeManager.single_color(self.button_color, self.appearance_mode),
outline=ThemeManager.single_color(self.button_color, self.appearance_mode))
if self.text_label is None:
self.text_label = tkinter.Label(master=self,
@ -178,8 +178,8 @@ class CTkSwitch(CTkBaseClass):
if self.textvariable is not None:
self.text_label.configure(textvariable=self.textvariable)
self.text_label.configure(fg=CTkThemeManager.single_color(self.text_color, self.appearance_mode))
self.text_label.configure(bg=CTkThemeManager.single_color(self.bg_color, self.appearance_mode))
self.text_label.configure(fg=ThemeManager.single_color(self.text_color, self.appearance_mode))
self.text_label.configure(bg=ThemeManager.single_color(self.bg_color, self.appearance_mode))
self.set_text(self.text)
@ -235,13 +235,13 @@ class CTkSwitch(CTkBaseClass):
def on_enter(self, event=0):
self.hover_state = True
self.canvas.itemconfig("slider_parts", fill=CTkThemeManager.single_color(self.button_hover_color, self.appearance_mode),
outline=CTkThemeManager.single_color(self.button_hover_color, self.appearance_mode))
self.canvas.itemconfig("slider_parts", fill=ThemeManager.single_color(self.button_hover_color, self.appearance_mode),
outline=ThemeManager.single_color(self.button_hover_color, self.appearance_mode))
def on_leave(self, event=0):
self.hover_state = False
self.canvas.itemconfig("slider_parts", fill=CTkThemeManager.single_color(self.button_color, self.appearance_mode),
outline=CTkThemeManager.single_color(self.button_color, self.appearance_mode))
self.canvas.itemconfig("slider_parts", fill=ThemeManager.single_color(self.button_color, self.appearance_mode),
outline=ThemeManager.single_color(self.button_color, self.appearance_mode))
def variable_callback(self, var_name, index, mode):
if not self.variable_callback_blocked:

View File

@ -8,7 +8,7 @@ from ..windows.ctk_tk import CTk
from ..windows.ctk_toplevel import CTkToplevel
from ..appearance_mode_tracker import AppearanceModeTracker
from ..scaling_tracker import ScalingTracker
from ..ctk_theme_manager import CTkThemeManager
from ..theme_manager import ThemeManager
class CTkBaseClass(tkinter.Frame):
@ -41,7 +41,7 @@ class CTkBaseClass(tkinter.Frame):
AppearanceModeTracker.add(self.set_appearance_mode, self)
self.appearance_mode = AppearanceModeTracker.get_mode() # 0: "Light" 1: "Dark"
super().configure(bg=CTkThemeManager.single_color(self.bg_color, self.appearance_mode))
super().configure(bg=ThemeManager.single_color(self.bg_color, self.appearance_mode))
# overwrite configure methods of master when master is tkinter widget, so that bg changes get applied on child CTk widget too
if isinstance(self.master, (tkinter.Tk, tkinter.Toplevel, tkinter.Frame)) and not isinstance(self.master, (CTkBaseClass, CTk, CTkToplevel)):

View File

@ -7,7 +7,7 @@ from ..widgets.ctk_frame import CTkFrame
from ..windows.ctk_toplevel import CTkToplevel
from ..widgets.ctk_button import CTkButton
from ..appearance_mode_tracker import AppearanceModeTracker
from ..ctk_theme_manager import CTkThemeManager
from ..theme_manager import ThemeManager
class CTkInputDialog:
@ -27,10 +27,10 @@ class CTkInputDialog:
self.height = len(text.split("\n"))*20 + 150
self.window_bg_color = CTkThemeManager.theme["color"]["window_bg_color"]
self.fg_color = CTkThemeManager.theme["color"]["button"] if fg_color == "default_theme" else fg_color
self.hover_color = CTkThemeManager.theme["color"]["button_hover"] if hover_color == "default_theme" else hover_color
self.border_color = CTkThemeManager.theme["color"]["button_hover"] if border_color == "default_theme" else border_color
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.top = CTkToplevel()
self.top.geometry(f"{280}x{self.height}")

View File

@ -8,9 +8,9 @@ import re
from typing import Union, Tuple
from ..appearance_mode_tracker import AppearanceModeTracker
from ..ctk_theme_manager import CTkThemeManager
from ..theme_manager import ThemeManager
from ..scaling_tracker import ScalingTracker
from ..ctk_settings import CTkSettings
from ..settings import Settings
class CTk(tkinter.Tk):
@ -39,7 +39,7 @@ class CTk(tkinter.Tk):
self.max_height: int = 1_000_000
self.last_resizable_args: Union[Tuple[list, dict], None] = None # (args, kwargs)
self.fg_color = CTkThemeManager.theme["color"]["window_bg_color"] if fg_color == "default_theme" else fg_color
self.fg_color = ThemeManager.theme["color"]["window_bg_color"] if fg_color == "default_theme" else fg_color
if "bg" in kwargs:
self.fg_color = kwargs["bg"]
@ -48,7 +48,7 @@ class CTk(tkinter.Tk):
self.fg_color = kwargs["background"]
del kwargs["background"]
super().configure(bg=CTkThemeManager.single_color(self.fg_color, self.appearance_mode))
super().configure(bg=ThemeManager.single_color(self.fg_color, self.appearance_mode))
super().title("CTk")
self.geometry(f"{self.current_width}x{self.current_height}")
@ -171,14 +171,14 @@ class CTk(tkinter.Tk):
if "bg" in kwargs:
self.fg_color = kwargs["bg"]
bg_changed = True
kwargs["bg"] = CTkThemeManager.single_color(self.fg_color, self.appearance_mode)
kwargs["bg"] = ThemeManager.single_color(self.fg_color, self.appearance_mode)
elif "background" in kwargs:
self.fg_color = kwargs["background"]
bg_changed = True
kwargs["background"] = CTkThemeManager.single_color(self.fg_color, self.appearance_mode)
kwargs["background"] = ThemeManager.single_color(self.fg_color, self.appearance_mode)
elif "fg_color" in kwargs:
self.fg_color = kwargs["fg_color"]
kwargs["bg"] = CTkThemeManager.single_color(self.fg_color, self.appearance_mode)
kwargs["bg"] = ThemeManager.single_color(self.fg_color, self.appearance_mode)
del kwargs["fg_color"]
bg_changed = True
@ -186,11 +186,11 @@ class CTk(tkinter.Tk):
if "bg" in args[0]:
self.fg_color=args[0]["bg"]
bg_changed = True
args[0]["bg"] = CTkThemeManager.single_color(self.fg_color, self.appearance_mode)
args[0]["bg"] = ThemeManager.single_color(self.fg_color, self.appearance_mode)
elif "background" in args[0]:
self.fg_color=args[0]["background"]
bg_changed = True
args[0]["background"] = CTkThemeManager.single_color(self.fg_color, self.appearance_mode)
args[0]["background"] = ThemeManager.single_color(self.fg_color, self.appearance_mode)
if bg_changed:
from ..widgets.widget_base_class import CTkBaseClass
@ -203,7 +203,7 @@ class CTk(tkinter.Tk):
@staticmethod
def enable_macos_dark_title_bar():
if sys.platform == "darwin" and not CTkSettings.deactivate_macos_window_header_manipulation: # macOS
if sys.platform == "darwin" and not Settings.deactivate_macos_window_header_manipulation: # macOS
if Version(platform.python_version()) < Version("3.10"):
if Version(tkinter.Tcl().call("info", "patchlevel")) >= Version("8.6.9"): # Tcl/Tk >= 8.6.9
os.system("defaults write -g NSRequiresAquaSystemAppearance -bool No")
@ -211,7 +211,7 @@ class CTk(tkinter.Tk):
@staticmethod
def disable_macos_dark_title_bar():
if sys.platform == "darwin" and not CTkSettings.deactivate_macos_window_header_manipulation: # macOS
if sys.platform == "darwin" and not Settings.deactivate_macos_window_header_manipulation: # macOS
if Version(platform.python_version()) < Version("3.10"):
if Version(tkinter.Tcl().call("info", "patchlevel")) >= Version("8.6.9"): # Tcl/Tk >= 8.6.9
os.system("defaults delete -g NSRequiresAquaSystemAppearance")
@ -228,7 +228,7 @@ class CTk(tkinter.Tk):
https://docs.microsoft.com/en-us/windows/win32/api/dwmapi/ne-dwmapi-dwmwindowattribute
"""
if sys.platform.startswith("win") and not CTkSettings.deactivate_windows_window_header_manipulation:
if sys.platform.startswith("win") and not Settings.deactivate_windows_window_header_manipulation:
super().withdraw() # hide window so that it can be redrawn after the titlebar change so that the color change is visible
if not self.window_exists:
@ -274,4 +274,4 @@ class CTk(tkinter.Tk):
else:
self.windows_set_titlebar_color("light")
super().configure(bg=CTkThemeManager.single_color(self.fg_color, self.appearance_mode))
super().configure(bg=ThemeManager.single_color(self.fg_color, self.appearance_mode))

View File

@ -8,8 +8,8 @@ import re
from typing import Union, Tuple
from ..appearance_mode_tracker import AppearanceModeTracker
from ..ctk_theme_manager import CTkThemeManager
from ..ctk_settings import CTkSettings
from ..theme_manager import ThemeManager
from ..settings import Settings
from ..scaling_tracker import ScalingTracker
@ -34,7 +34,7 @@ class CTkToplevel(tkinter.Toplevel):
self.max_height: int = 1_000_000
self.last_resizable_args: Union[Tuple[list, dict], None] = None # (args, kwargs)
self.fg_color = CTkThemeManager.theme["color"]["window_bg_color"] if fg_color == "default_theme" else fg_color
self.fg_color = ThemeManager.theme["color"]["window_bg_color"] if fg_color == "default_theme" else fg_color
if "bg" in kwargs:
self.fg_color = kwargs["bg"]
@ -45,7 +45,7 @@ class CTkToplevel(tkinter.Toplevel):
# add set_appearance_mode method to callback list of AppearanceModeTracker for appearance mode changes
AppearanceModeTracker.add(self.set_appearance_mode, self)
super().configure(bg=CTkThemeManager.single_color(self.fg_color, self.appearance_mode))
super().configure(bg=ThemeManager.single_color(self.fg_color, self.appearance_mode))
super().title("CTkToplevel")
if sys.platform.startswith("win"):
@ -151,14 +151,14 @@ class CTkToplevel(tkinter.Toplevel):
if "bg" in kwargs:
self.fg_color = kwargs["bg"]
bg_changed = True
kwargs["bg"] = CTkThemeManager.single_color(self.fg_color, self.appearance_mode)
kwargs["bg"] = ThemeManager.single_color(self.fg_color, self.appearance_mode)
elif "background" in kwargs:
self.fg_color = kwargs["background"]
bg_changed = True
kwargs["background"] = CTkThemeManager.single_color(self.fg_color, self.appearance_mode)
kwargs["background"] = ThemeManager.single_color(self.fg_color, self.appearance_mode)
elif "fg_color" in kwargs:
self.fg_color = kwargs["fg_color"]
kwargs["bg"] = CTkThemeManager.single_color(self.fg_color, self.appearance_mode)
kwargs["bg"] = ThemeManager.single_color(self.fg_color, self.appearance_mode)
del kwargs["fg_color"]
bg_changed = True
@ -166,11 +166,11 @@ class CTkToplevel(tkinter.Toplevel):
if "bg" in args[0]:
self.fg_color=args[0]["bg"]
bg_changed = True
args[0]["bg"] = CTkThemeManager.single_color(self.fg_color, self.appearance_mode)
args[0]["bg"] = ThemeManager.single_color(self.fg_color, self.appearance_mode)
elif "background" in args[0]:
self.fg_color=args[0]["background"]
bg_changed = True
args[0]["background"] = CTkThemeManager.single_color(self.fg_color, self.appearance_mode)
args[0]["background"] = ThemeManager.single_color(self.fg_color, self.appearance_mode)
if bg_changed:
from ..widgets.widget_base_class import CTkBaseClass
@ -183,14 +183,14 @@ class CTkToplevel(tkinter.Toplevel):
@staticmethod
def enable_macos_dark_title_bar():
if sys.platform == "darwin" and not CTkSettings.deactivate_macos_window_header_manipulation: # macOS
if sys.platform == "darwin" and not Settings.deactivate_macos_window_header_manipulation: # macOS
if Version(platform.python_version()) < Version("3.10"):
if Version(tkinter.Tcl().call("info", "patchlevel")) >= Version("8.6.9"): # Tcl/Tk >= 8.6.9
os.system("defaults write -g NSRequiresAquaSystemAppearance -bool No")
@staticmethod
def disable_macos_dark_title_bar():
if sys.platform == "darwin" and not CTkSettings.deactivate_macos_window_header_manipulation: # macOS
if sys.platform == "darwin" and not Settings.deactivate_macos_window_header_manipulation: # macOS
if Version(platform.python_version()) < Version("3.10"):
if Version(tkinter.Tcl().call("info", "patchlevel")) >= Version("8.6.9"): # Tcl/Tk >= 8.6.9
os.system("defaults delete -g NSRequiresAquaSystemAppearance")
@ -207,7 +207,7 @@ class CTkToplevel(tkinter.Toplevel):
https://docs.microsoft.com/en-us/windows/win32/api/dwmapi/ne-dwmapi-dwmwindowattribute
"""
if sys.platform.startswith("win") and not CTkSettings.deactivate_windows_window_header_manipulation:
if sys.platform.startswith("win") and not Settings.deactivate_windows_window_header_manipulation:
super().withdraw() # hide window so that it can be redrawn after the titlebar change so that the color change is visible
super().update()
@ -250,4 +250,4 @@ class CTkToplevel(tkinter.Toplevel):
else:
self.windows_set_titlebar_color("light")
super().configure(bg=CTkThemeManager.single_color(self.fg_color, self.appearance_mode))
super().configure(bg=ThemeManager.single_color(self.fg_color, self.appearance_mode))

View File

@ -2,7 +2,7 @@ import tkinter
import customtkinter # <- import the CustomTkinter module
customtkinter.set_appearance_mode("dark") # Modes: "System" (standard), "Dark", "Light"
customtkinter.set_default_color_theme("blue") # Themes: "blue" (standard), "green", "dark-blue"
# customtkinter.set_default_color_theme("blue") # Themes: "blue" (standard), "green", "dark-blue"
root_tk = customtkinter.CTk() # create CTk window like you do with the Tk window (you can also use normal tkinter.Tk window)
root_tk.geometry("400x480")

View File

@ -46,5 +46,5 @@ for i in range(0, 21, 1):
border_color="gray10", fg_color="#228da8")
b.grid(row=i, column=0, pady=5, padx=15, sticky="nsew")
customtkinter.CTkSettings.print_settings()
app.mainloop()
customtkinter.Settings.print_settings()
app.mainloop()