restructured settings, small scaling fixes in CTk

This commit is contained in:
TomSchimansky
2022-05-22 00:02:45 +02:00
parent 4b48bf57b2
commit 35bdbed95c
21 changed files with 135 additions and 408 deletions

View File

@@ -9,32 +9,30 @@ 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()
from .draw_engine import DrawEngine
AppearanceModeTracker.init_appearance_mode()
ThemeManager.load_theme("blue")
FontManager.init_font_manager()
# determine draw method based on current platform
if sys.platform == "darwin":
DrawEngine.preferred_drawing_method = "polygon_shapes"
else:
DrawEngine.preferred_drawing_method = "font_shapes"
# 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
else:
Settings.circle_font_is_ready = False
if Settings.preferred_drawing_method == "font_shapes":
if FontManager.load_font(os.path.join(script_directory, "assets", "fonts", "CustomTkinter_shapes_font-fine.otf")) is False:
if DrawEngine.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"
DrawEngine.preferred_drawing_method = "circle_shapes"
# import widgets
from .widgets.ctk_button import CTkButton
@@ -69,10 +67,10 @@ def set_default_color_theme(color_string):
ThemeManager.load_theme(color_string)
def deactivate_dpi_awareness(deactivate_awareness: bool):
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)
def deactivate_automatic_dpi_awareness():
ScalingTracker.deactivate_automatic_dpi_awareness = False

View File

@@ -98,7 +98,7 @@ class AppearanceModeTracker:
# find an existing tkinter.Tk object for the next call of .after()
for root_tk in cls.root_tk_list:
try:
root_tk.after(200, cls.update)
root_tk.after(500, cls.update)
return
except Exception:
continue

View File

@@ -51,7 +51,7 @@
"radiobutton_border_width_unchecked": 3,
"radiobutton_border_width_checked": 6,
"entry_border_width": 2,
"frame_corner_radius": 10,
"frame_corner_radius": 8,
"frame_border_width": 0,
"label_corner_radius": 8,
"progressbar_border_width": 0,
@@ -65,4 +65,4 @@
"switch_button_corner_radius": 1000,
"switch_button_length": 0
}
}
}

View File

@@ -1,9 +1,11 @@
from __future__ import annotations
import sys
import math
import tkinter
from typing import Union
from typing import Union, TYPE_CHECKING
from .widgets.ctk_canvas import CTkCanvas
if TYPE_CHECKING:
from .widgets.ctk_canvas import CTkCanvas
class DrawEngine:
@@ -21,25 +23,26 @@ class DrawEngine:
"""
def __init__(self, canvas: CTkCanvas, rendering_method: str):
preferred_drawing_method: str = None # 'polygon_shapes', 'font_shapes', 'circle_shapes'
def __init__(self, canvas: CTkCanvas):
self._canvas = canvas
self._rendering_method = rendering_method # "polygon_shapes" (macOS), "font_shapes" (Windows, Linux), "circle_shapes" (backup without fonts)
self._existing_tags = set()
def _calc_optimal_corner_radius(self, user_corner_radius: Union[float, int]) -> Union[float, int]:
# optimize for drawing with polygon shapes
if self._rendering_method == "polygon_shapes":
if self.preferred_drawing_method == "polygon_shapes":
if sys.platform == "darwin":
return user_corner_radius
else:
return round(user_corner_radius)
# optimize forx drawing with antialiased font shapes
elif self._rendering_method == "font_shapes":
elif self.preferred_drawing_method == "font_shapes":
return round(user_corner_radius)
# optimize for drawing with circles and rects
elif self._rendering_method == "circle_shapes":
elif self.preferred_drawing_method == "circle_shapes":
user_corner_radius = 0.5 * round(user_corner_radius / 0.5) # round to 0.5 steps
# make sure the value is always with .5 at the end for smoother corners
@@ -71,11 +74,11 @@ class DrawEngine:
else:
inner_corner_radius = 0
if self._rendering_method == "polygon_shapes":
if self.preferred_drawing_method == "polygon_shapes":
return self._draw_rounded_rect_with_border_polygon_shapes(width, height, corner_radius, border_width, inner_corner_radius)
elif self._rendering_method == "font_shapes":
elif self.preferred_drawing_method == "font_shapes":
return self._draw_rounded_rect_with_border_font_shapes(width, height, corner_radius, border_width, inner_corner_radius, ())
elif self._rendering_method == "circle_shapes":
elif self.preferred_drawing_method == "circle_shapes":
return self._draw_rounded_rect_with_border_circle_shapes(width, height, corner_radius, border_width, inner_corner_radius)
def _draw_rounded_rect_with_border_polygon_shapes(self, width: int, height: int, corner_radius: int, border_width: int, inner_corner_radius: int) -> bool:
@@ -365,10 +368,10 @@ class DrawEngine:
else:
inner_corner_radius = 0
if self._rendering_method == "polygon_shapes" or self._rendering_method == "circle_shapes":
if self.preferred_drawing_method == "polygon_shapes" or self.preferred_drawing_method == "circle_shapes":
return self._draw_rounded_progress_bar_with_border_polygon_shapes(width, height, corner_radius, border_width, inner_corner_radius,
progress_value, orientation)
elif self._rendering_method == "font_shapes":
elif self.preferred_drawing_method == "font_shapes":
return self._draw_rounded_progress_bar_with_border_font_shapes(width, height, corner_radius, border_width, inner_corner_radius,
progress_value, orientation)
@@ -534,10 +537,10 @@ class DrawEngine:
else:
inner_corner_radius = 0
if self._rendering_method == "polygon_shapes" or self._rendering_method == "circle_shapes":
if self.preferred_drawing_method == "polygon_shapes" or self.preferred_drawing_method == "circle_shapes":
return self._draw_rounded_slider_with_border_and_button_polygon_shapes(width, height, corner_radius, border_width, inner_corner_radius,
button_length, button_corner_radius, slider_value, orientation)
elif self._rendering_method == "font_shapes":
elif self.preferred_drawing_method == "font_shapes":
return self._draw_rounded_slider_with_border_and_button_font_shapes(width, height, corner_radius, border_width, inner_corner_radius,
button_length, button_corner_radius, slider_value, orientation)
@@ -659,7 +662,7 @@ class DrawEngine:
size = round(size)
requires_recoloring = False
if self._rendering_method == "polygon_shapes" or self._rendering_method == "circle_shapes":
if self.preferred_drawing_method == "polygon_shapes" or self.preferred_drawing_method == "circle_shapes":
x, y, radius = width / 2, height / 2, size / 2.8
if not self._canvas.find_withtag("checkmark"):
self._canvas.create_line(0, 0, 0, 0, tags=("checkmark", "create_line"), width=round(height / 8), joinstyle=tkinter.MITER, capstyle=tkinter.ROUND)
@@ -670,7 +673,7 @@ class DrawEngine:
x + radius, y - radius,
x - radius / 4, y + radius * 0.8,
x - radius, y + radius / 6)
elif self._rendering_method == "font_shapes":
elif self.preferred_drawing_method == "font_shapes":
if not self._canvas.find_withtag("checkmark"):
self._canvas.create_text(0, 0, text="Z", font=("CustomTkinter_shapes_font", -size), tags=("checkmark", "create_text"), anchor=tkinter.CENTER)
self._canvas.tag_raise("checkmark")

View File

@@ -1,11 +1,10 @@
import tkinter
import sys
from typing import Callable, Type
from .settings import Settings
from typing import Callable
class ScalingTracker:
deactivate_automatic_dpi_awareness = False
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
@@ -34,17 +33,17 @@ class ScalingTracker:
@classmethod
def set_widget_scaling(cls, widget_scaling_factor: float):
cls.widget_scaling = max(widget_scaling_factor, 0.4)
cls.update_scaling_callbacks()
cls.update_scaling_callbacks_all()
@classmethod
def set_spacing_scaling(cls, spacing_scaling_factor: float):
cls.spacing_scaling = max(spacing_scaling_factor, 0.4)
cls.update_scaling_callbacks()
cls.update_scaling_callbacks_all()
@classmethod
def set_window_scaling(cls, window_scaling_factor: float):
cls.window_scaling = max(window_scaling_factor, 0.4)
cls.update_scaling_callbacks()
cls.update_scaling_callbacks_all()
@classmethod
def get_window_root_of_widget(cls, widget):
@@ -57,17 +56,29 @@ class ScalingTracker:
return current_widget
@classmethod
def update_scaling_callbacks(cls):
def update_scaling_callbacks_all(cls):
for window, callback_list in cls.window_widgets_dict.items():
for callback in callback_list:
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)
for set_scaling_callback in callback_list:
if not cls.deactivate_automatic_dpi_awareness:
set_scaling_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)
else:
callback(cls.widget_scaling,
cls.spacing_scaling,
cls.window_scaling)
set_scaling_callback(cls.widget_scaling,
cls.spacing_scaling,
cls.window_scaling)
@classmethod
def update_scaling_callbacks_for_window(cls, window):
for set_scaling_callback in cls.window_widgets_dict[window]:
if not cls.deactivate_automatic_dpi_awareness:
set_scaling_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)
else:
set_scaling_callback(cls.widget_scaling,
cls.spacing_scaling,
cls.window_scaling)
@classmethod
def add_widget(cls, widget_callback: Callable, widget):
@@ -81,9 +92,9 @@ class ScalingTracker:
if window_root not in cls.window_dpi_scaling_dict:
cls.window_dpi_scaling_dict[window_root] = cls.get_window_dpi_scaling(window_root)
#if not cls.update_loop_running:
# window_root.after(100, cls.check_dpi_scaling)
# cls.update_loop_running = True
if not cls.update_loop_running:
window_root.after(100, cls.check_dpi_scaling)
cls.update_loop_running = True
@classmethod
def remove_widget(cls, widget_callback, widget):
@@ -115,7 +126,7 @@ class ScalingTracker:
""" make process DPI aware, customtkinter elemets will get scaled automatically,
only gets activated when CTk object is created """
if not Settings.deactivate_automatic_dpi_awareness:
if not cls.deactivate_automatic_dpi_awareness:
if sys.platform == "darwin":
pass # high DPI scaling works automatically on macOS
@@ -151,10 +162,16 @@ class ScalingTracker:
# check for every window if scaling value changed
# (not implemented yet)
for window in cls.window_widgets_dict:
current_dpi_scaling_value = cls.get_window_dpi_scaling(window)
if current_dpi_scaling_value != cls.window_dpi_scaling_dict[window]:
cls.window_dpi_scaling_dict[window] = current_dpi_scaling_value
cls.update_scaling_callbacks_for_window(window)
# find an existing tkinter object for the next call of .after()
for root_tk in cls.window_widgets_dict.keys():
try:
root_tk.after(500, cls.check_dpi_scaling)
root_tk.after(200, cls.check_dpi_scaling)
return
except Exception:
continue

View File

@@ -1,42 +1,5 @@
import sys
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
deactivate_automatic_dpi_awareness = False
@classmethod
def init_font_character_mapping(cls):
""" optimizations made for Windows 10, 11 only """
radius_to_char_warped = {19: 'B', 18: 'B', 17: 'B', 16: 'B', 15: 'B', 14: 'B', 13: 'B', 12: 'B', 11: 'B', 10: 'B',
9: 'C', 8: 'D', 7: 'C', 6: 'E', 5: 'F', 4: 'G', 3: 'H', 2: 'H', 1: 'H', 0: 'A'}
radius_to_char_fine_windows_10 = {19: 'A', 18: 'A', 17: 'B', 16: 'B', 15: 'B', 14: 'B', 13: 'C', 12: 'C', 11: 'C', 10: 'C',
9: 'D', 8: 'D', 7: 'D', 6: 'F', 5: 'D', 4: 'G', 3: 'G', 2: 'H', 1: 'H', 0: 'A'}
radius_to_char_fine_windows_11 = {19: 'A', 18: 'A', 17: 'B', 16: 'B', 15: 'B', 14: 'B', 13: 'C', 12: 'C', 11: 'D', 10: 'D',
9: 'E', 8: 'F', 7: 'C', 6: 'I', 5: 'E', 4: 'G', 3: 'P', 2: 'R', 1: 'R', 0: 'A'}
if sys.platform.startswith("win"):
if sys.getwindowsversion().build > 20000: # Windows 11
cls.radius_to_char_fine = radius_to_char_fine_windows_11
else: # < Windows 11
cls.radius_to_char_fine = radius_to_char_fine_windows_10
else: # macOS and Linux
cls.radius_to_char_fine = radius_to_char_fine_windows_10
@classmethod
def init_drawing_method(cls):
""" possible: 'polygon_shapes', 'font_shapes', 'circle_shapes' """
if sys.platform == "darwin":
cls.preferred_drawing_method = "polygon_shapes"
else:
cls.preferred_drawing_method = "font_shapes"

View File

@@ -0,0 +1,3 @@
from .ctk_canvas import CTkCanvas
CTkCanvas.init_font_character_mapping()

View File

@@ -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 = DrawEngine(self.canvas, Settings.preferred_drawing_method)
self.draw_engine = DrawEngine(self.canvas)
# event bindings
self.canvas.bind("<Enter>", self.on_enter)

View File

@@ -1,23 +1,50 @@
import tkinter
from ..settings import Settings
import sys
from typing import Union
class CTkCanvas(tkinter.Canvas):
radius_to_char_fine = Settings.radius_to_char_fine # dict to map radius to font circle character
radius_to_char_fine: dict = None # dict to map radius to font circle character
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.aa_circle_canvas_ids = set()
def get_char_from_radius(self, radius):
@classmethod
def init_font_character_mapping(cls):
""" optimizations made for Windows 10, 11 only """
radius_to_char_warped = {19: 'B', 18: 'B', 17: 'B', 16: 'B', 15: 'B', 14: 'B', 13: 'B', 12: 'B', 11: 'B',
10: 'B',
9: 'C', 8: 'D', 7: 'C', 6: 'E', 5: 'F', 4: 'G', 3: 'H', 2: 'H', 1: 'H', 0: 'A'}
radius_to_char_fine_windows_10 = {19: 'A', 18: 'A', 17: 'B', 16: 'B', 15: 'B', 14: 'B', 13: 'C', 12: 'C',
11: 'C', 10: 'C',
9: 'D', 8: 'D', 7: 'D', 6: 'F', 5: 'D', 4: 'G', 3: 'G', 2: 'H', 1: 'H',
0: 'A'}
radius_to_char_fine_windows_11 = {19: 'A', 18: 'A', 17: 'B', 16: 'B', 15: 'B', 14: 'B', 13: 'C', 12: 'C',
11: 'D', 10: 'D',
9: 'E', 8: 'F', 7: 'C', 6: 'I', 5: 'E', 4: 'G', 3: 'P', 2: 'R', 1: 'R',
0: 'A'}
if sys.platform.startswith("win"):
if sys.getwindowsversion().build > 20000: # Windows 11
cls.radius_to_char_fine = radius_to_char_fine_windows_11
else: # < Windows 11
cls.radius_to_char_fine = radius_to_char_fine_windows_10
else: # macOS and Linux
cls.radius_to_char_fine = radius_to_char_fine_windows_10
def get_char_from_radius(self, radius: int) -> str:
if radius >= 20:
return "A"
else:
return self.radius_to_char_fine[radius]
def create_aa_circle(self, x_pos, y_pos, radius, angle=0, fill="white", tags="", anchor=tkinter.CENTER) -> str:
def create_aa_circle(self, x_pos: int, y_pos: int, radius: int, angle: int = 0, fill: str = "white",
tags: Union[str, tuple[str, ...]] = "", anchor: str = tkinter.CENTER) -> int:
# create a circle with a font element
circle_1 = self.create_text(x_pos, y_pos, text=self.get_char_from_radius(radius), anchor=anchor, fill=fill,
font=("CustomTkinter_shapes_font", -radius * 2), tags=tags, angle=angle)
@@ -61,5 +88,3 @@ class CTkCanvas(tkinter.Canvas):
super().itemconfigure(configure_id, *args, **kwargs_except_outline)
else:
super().itemconfigure(configure_id, *args, **kwargs)

View File

@@ -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 = DrawEngine(self.canvas, Settings.preferred_drawing_method)
self.draw_engine = DrawEngine(self.canvas)
if self.hover is True:
self.canvas.bind("<Enter>", self.on_enter)

View File

@@ -50,7 +50,7 @@ class CTkEntry(CTkBaseClass):
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 = DrawEngine(self.canvas, Settings.preferred_drawing_method)
self.draw_engine = DrawEngine(self.canvas)
self.entry = tkinter.Entry(master=self,
bd=0,

View File

@@ -45,7 +45,7 @@ class CTkFrame(CTkBaseClass):
height=self.apply_widget_scaling(self.current_height))
self.canvas.place(x=0, y=0, relwidth=1, relheight=1)
self.canvas.configure(bg=ThemeManager.single_color(self.bg_color, self.appearance_mode))
self.draw_engine = DrawEngine(self.canvas, Settings.preferred_drawing_method)
self.draw_engine = DrawEngine(self.canvas)
self.bind('<Configure>', self.update_dimensions_event)

View File

@@ -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 = DrawEngine(self.canvas, Settings.preferred_drawing_method)
self.draw_engine = DrawEngine(self.canvas)
self.text_label = tkinter.Label(master=self,
highlightthickness=0,

View File

@@ -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 = DrawEngine(self.canvas, Settings.preferred_drawing_method)
self.draw_engine = DrawEngine(self.canvas)
# 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)

View File

@@ -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 = DrawEngine(self.canvas, Settings.preferred_drawing_method)
self.draw_engine = DrawEngine(self.canvas)
self.canvas.bind("<Enter>", self.on_enter)
self.canvas.bind("<Leave>", self.on_leave)

View File

@@ -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 = DrawEngine(self.canvas, Settings.preferred_drawing_method)
self.draw_engine = DrawEngine(self.canvas)
self.canvas.bind("<Enter>", self.on_enter)
self.canvas.bind("<Leave>", self.on_leave)

View File

@@ -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 = DrawEngine(self.canvas, Settings.preferred_drawing_method)
self.draw_engine = DrawEngine(self.canvas)
self.canvas.bind("<Enter>", self.on_enter)
self.canvas.bind("<Leave>", self.on_leave)

View File

@@ -69,24 +69,21 @@ class CTk(tkinter.Tk):
if self.current_width != round(detected_width / self.window_scaling) or self.current_height != round(detected_height / self.window_scaling):
self.current_width = round(detected_width / self.window_scaling) # adjust current size according to new size given by event
self.current_height = round(detected_height / self.window_scaling) # current_width and current_height are independent of the scale
print("update_dimensions_event:", self.current_width)
def set_scaling(self, new_widget_scaling, new_spacing_scaling, new_window_scaling):
self.window_scaling = new_window_scaling
# reset min, max and resizable constraints for applying scaling
if self.last_resizable_args is not None:
super().resizable(True, True)
if self.min_width is not None or self.min_height is not None:
super().minsize(0, 0)
if self.max_width is not None or self.max_height is not None:
super().maxsize(1_000_000, 1_000_000)
# force new dimensions on window by using min, max, and geometry
super().minsize(self.apply_window_scaling(self.current_width), self.apply_window_scaling(self.current_height))
super().maxsize(self.apply_window_scaling(self.current_width), self.apply_window_scaling(self.current_height))
super().geometry(f"{self.apply_window_scaling(self.current_width)}x"+f"{self.apply_window_scaling(self.current_height)}")
print("set_scaling:", self.apply_window_scaling(self.current_width), self.max_width, self.min_width)
# set new window size by applying scaling to the current window size
self.geometry(f"{self.current_width}x{self.current_height}")
# set new scaled min and max with 400ms delay (otherwise it won't work for some reason)
self.after(400, self.set_scaled_min_max)
# set scaled min, max sizes and reapply resizable
if self.last_resizable_args is not None:
super().resizable(*self.last_resizable_args[0], **self.last_resizable_args[1]) # args, kwargs
def set_scaled_min_max(self):
if self.min_width is not None or self.min_height is not None:
super().minsize(self.apply_window_scaling(self.min_width), self.apply_window_scaling(self.min_height))
if self.max_width is not None or self.max_height is not None:
@@ -106,6 +103,7 @@ class CTk(tkinter.Tk):
def mainloop(self, *args, **kwargs):
if not self.window_exists:
print("deiconify")
self.deiconify()
self.window_exists = True
super().mainloop(*args, **kwargs)
@@ -135,6 +133,7 @@ class CTk(tkinter.Tk):
super().maxsize(self.apply_window_scaling(self.max_width), self.apply_window_scaling(self.max_height))
def geometry(self, geometry_string):
print("geometry:", geometry_string)
super().geometry(self.apply_geometry_scaling(geometry_string))
# update width and height attributes