moved width and height configuring to CTkBaseClass

This commit is contained in:
Tom Schimansky
2022-10-14 12:52:07 +02:00
parent 6ba384eb0b
commit eabfa67335
14 changed files with 129 additions and 175 deletions

View File

@@ -322,12 +322,6 @@ class CTkButton(CTkBaseClass):
if self._text_label is not None: if self._text_label is not None:
self._text_label.configure(textvariable=self._textvariable) self._text_label.configure(textvariable=self._textvariable)
if "width" in kwargs:
self._set_dimensions(width=kwargs.pop("width"))
if "height" in kwargs:
self._set_dimensions(height=kwargs.pop("height"))
if "background_corner_colors" in kwargs: if "background_corner_colors" in kwargs:
self._background_corner_colors = kwargs.pop("background_corner_colors") self._background_corner_colors = kwargs.pop("background_corner_colors")
require_redraw = True require_redraw = True

View File

@@ -225,12 +225,6 @@ class CTkComboBox(CTkBaseClass):
self._variable = kwargs.pop("variable") self._variable = kwargs.pop("variable")
self._entry.configure(textvariable=self._variable) self._entry.configure(textvariable=self._variable)
if "width" in kwargs:
self._set_dimensions(width=kwargs.pop("width"))
if "height" in kwargs:
self._set_dimensions(height=kwargs.pop("height"))
if "values" in kwargs: if "values" in kwargs:
self._values = kwargs.pop("values") self._values = kwargs.pop("values")
self._dropdown_menu.configure(values=self._values) self._dropdown_menu.configure(values=self._values)

View File

@@ -193,12 +193,6 @@ class CTkEntry(CTkBaseClass):
padx=self._apply_widget_scaling(self._minimum_x_padding)) padx=self._apply_widget_scaling(self._minimum_x_padding))
require_redraw = True require_redraw = True
if "width" in kwargs:
self._set_dimensions(width=kwargs.pop("width"))
if "height" in kwargs:
self._set_dimensions(height=kwargs.pop("height"))
if "placeholder_text" in kwargs: if "placeholder_text" in kwargs:
self._placeholder_text = kwargs.pop("placeholder_text") self._placeholder_text = kwargs.pop("placeholder_text")
if self._placeholder_text_active: if self._placeholder_text_active:

View File

@@ -163,12 +163,6 @@ class CTkFrame(CTkBaseClass):
self._border_width = kwargs.pop("border_width") self._border_width = kwargs.pop("border_width")
require_redraw = True require_redraw = True
if "width" in kwargs:
self._set_dimensions(width=kwargs.pop("width"))
if "height" in kwargs:
self._set_dimensions(height=kwargs.pop("height"))
super().configure(require_redraw=require_redraw, **kwargs) super().configure(require_redraw=require_redraw, **kwargs)
def cget(self, attribute_name: str) -> any: def cget(self, attribute_name: str) -> any:

View File

@@ -145,12 +145,6 @@ class CTkLabel(CTkBaseClass):
self._text_color = kwargs.pop("text_color") self._text_color = kwargs.pop("text_color")
require_redraw = True require_redraw = True
if "width" in kwargs:
self._set_dimensions(width=kwargs.pop("width"))
if "height" in kwargs:
self._set_dimensions(height=kwargs.pop("height"))
if "corner_radius" in kwargs: if "corner_radius" in kwargs:
self._corner_radius = kwargs.pop("corner_radius") self._corner_radius = kwargs.pop("corner_radius")
text_label_grid_sticky = self._anchor if self._anchor != "center" else "" text_label_grid_sticky = self._anchor if self._anchor != "center" else ""

View File

@@ -244,12 +244,6 @@ class CTkOptionMenu(CTkBaseClass):
else: else:
self._variable = None self._variable = None
if "width" in kwargs:
self._set_dimensions(width=kwargs.pop("width"))
if "height" in kwargs:
self._set_dimensions(height=kwargs.pop("height"))
if "values" in kwargs: if "values" in kwargs:
self._values = kwargs.pop("values") self._values = kwargs.pop("values")
self._dropdown_menu.configure(values=self._values) self._dropdown_menu.configure(values=self._values)

View File

@@ -192,12 +192,6 @@ class CTkProgressBar(CTkBaseClass):
if "indeterminate_speed" in kwargs: if "indeterminate_speed" in kwargs:
self._indeterminate_speed = kwargs.pop("indeterminate_speed") self._indeterminate_speed = kwargs.pop("indeterminate_speed")
if "width" in kwargs:
self._set_dimensions(width=kwargs.pop("width"))
if "height" in kwargs:
self._set_dimensions(height=kwargs.pop("height"))
super().configure(require_redraw=require_redraw, **kwargs) super().configure(require_redraw=require_redraw, **kwargs)
def cget(self, attribute_name: str) -> any: def cget(self, attribute_name: str) -> any:

View File

@@ -175,12 +175,6 @@ class CTkScrollbar(CTkBaseClass):
self._border_spacing = kwargs.pop("border_spacing") self._border_spacing = kwargs.pop("border_spacing")
require_redraw = True require_redraw = True
if "width" in kwargs:
self._set_dimensions(width=kwargs.pop("width"))
if "height" in kwargs:
self._set_dimensions(height=kwargs.pop("height"))
super().configure(require_redraw=require_redraw, **kwargs) super().configure(require_redraw=require_redraw, **kwargs)
def cget(self, attribute_name: str) -> any: def cget(self, attribute_name: str) -> any:

View File

@@ -91,6 +91,12 @@ class CTkSegmentedButton(CTkFrame):
super().destroy() super().destroy()
def _set_dimensions(self, width: int = None, height: int = None):
super()._set_dimensions(width, height)
for button in self._buttons_dict.values():
button.configure(height=height)
def _variable_callback(self, var_name, index, mode): def _variable_callback(self, var_name, index, mode):
if not self._variable_callback_blocked: if not self._variable_callback_blocked:
self.set(self._variable.get(), from_variable_callback=True) self.set(self._variable.get(), from_variable_callback=True)
@@ -184,10 +190,6 @@ class CTkSegmentedButton(CTkFrame):
self._configure_button_corners_for_index(index) self._configure_button_corners_for_index(index)
def configure(self, **kwargs): def configure(self, **kwargs):
if "height" in kwargs:
for button in self._buttons_dict.values():
button.configure(height=kwargs["height"])
if "bg_color" in kwargs: if "bg_color" in kwargs:
super().configure(bg_color=kwargs.pop("bg_color")) super().configure(bg_color=kwargs.pop("bg_color"))

View File

@@ -245,12 +245,6 @@ class CTkSlider(CTkBaseClass):
else: else:
self._variable = None self._variable = None
if "width" in kwargs:
self._set_dimensions(width=kwargs.pop("width"))
if "height" in kwargs:
self._set_dimensions(height=kwargs.pop("height"))
super().configure(require_redraw=require_redraw, **kwargs) super().configure(require_redraw=require_redraw, **kwargs)
def cget(self, attribute_name: str) -> any: def cget(self, attribute_name: str) -> any:

View File

@@ -212,6 +212,9 @@ class CTkTabview(CTkBaseClass):
outline=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.configure(bg=ThemeManager.single_color(self._bg_color, self._appearance_mode))
def configure(self, **kwargs):
return
def tab(self, name: str) -> CTkFrame: def tab(self, name: str) -> CTkFrame:
""" returns reference to the tab with given name """ """ returns reference to the tab with given name """

View File

@@ -274,12 +274,6 @@ class CTkTextbox(CTkBaseClass):
self._create_grid_for_text_and_scrollbars(re_grid_textbox=True, re_grid_x_scrollbar=True, re_grid_y_scrollbar=True) self._create_grid_for_text_and_scrollbars(re_grid_textbox=True, re_grid_x_scrollbar=True, re_grid_y_scrollbar=True)
require_redraw = True require_redraw = True
if "width" in kwargs:
self._set_dimensions(width=kwargs.pop("width"))
if "height" in kwargs:
self._set_dimensions(height=kwargs.pop("height"))
if "font" in kwargs: if "font" in kwargs:
self._font = kwargs.pop("font") self._font = kwargs.pop("font")
self._textbox.configure(font=self._apply_font_scaling(self._font)) self._textbox.configure(font=self._apply_font_scaling(self._font))

View File

@@ -89,116 +89,6 @@ class CTkBaseClass(tkinter.Frame):
self.master.config = new_configure self.master.config = new_configure
self.master.configure = new_configure self.master.configure = new_configure
@staticmethod
def _check_kwargs_empty(kwargs_dict, raise_error=False) -> bool:
""" returns True if kwargs are empty, False otherwise, raises error if not empty """
if len(kwargs_dict) > 0:
if raise_error:
raise ValueError(f"{list(kwargs_dict.keys())} are not supported arguments. Look at the documentation for supported arguments.")
else:
return True
else:
return False
def destroy(self):
""" Destroy this and all descendants widgets. """
AppearanceModeTracker.remove(self._set_appearance_mode)
ScalingTracker.remove_widget(self._set_scaling, self)
super().destroy()
def place(self, **kwargs):
"""
Place a widget in the parent widget. Use as options:
in=master - master relative to which the widget is placed
in_=master - see 'in' option description
x=amount - locate anchor of this widget at position x of master
y=amount - locate anchor of this widget at position y of master
relx=amount - locate anchor of this widget between 0.0 and 1.0 relative to width of master (1.0 is right edge)
rely=amount - locate anchor of this widget between 0.0 and 1.0 relative to height of master (1.0 is bottom edge)
anchor=NSEW (or subset) - position anchor according to given direction
width=amount - width of this widget in pixel
height=amount - height of this widget in pixel
relwidth=amount - width of this widget between 0.0 and 1.0 relative to width of master (1.0 is the same width as the master)
relheight=amount - height of this widget between 0.0 and 1.0 relative to height of master (1.0 is the same height as the master)
bordermode="inside" or "outside" - whether to take border width of master widget into account
"""
self._last_geometry_manager_call = {"function": super().place, "kwargs": kwargs}
return super().place(**self._apply_argument_scaling(kwargs))
def place_forget(self):
""" Unmap this widget. """
self._last_geometry_manager_call = None
return super().place_forget()
def pack(self, **kwargs):
"""
Pack a widget in the parent widget. Use as options:
after=widget - pack it after you have packed widget
anchor=NSEW (or subset) - position widget according to given direction
before=widget - pack it before you will pack widget
expand=bool - expand widget if parent size grows
fill=NONE or X or Y or BOTH - fill widget if widget grows
in=master - use master to contain this widget
in_=master - see 'in' option description
ipadx=amount - add internal padding in x direction
ipady=amount - add internal padding in y direction
padx=amount - add padding in x direction
pady=amount - add padding in y direction
side=TOP or BOTTOM or LEFT or RIGHT - where to add this widget.
"""
self._last_geometry_manager_call = {"function": super().pack, "kwargs": kwargs}
return super().pack(**self._apply_argument_scaling(kwargs))
def pack_forget(self):
""" Unmap this widget and do not use it for the packing order. """
self._last_geometry_manager_call = None
return super().pack_forget()
def grid(self, **kwargs):
"""
Position a widget in the parent widget in a grid. Use as options:
column=number - use cell identified with given column (starting with 0)
columnspan=number - this widget will span several columns
in=master - use master to contain this widget
in_=master - see 'in' option description
ipadx=amount - add internal padding in x direction
ipady=amount - add internal padding in y direction
padx=amount - add padding in x direction
pady=amount - add padding in y direction
row=number - use cell identified with given row (starting with 0)
rowspan=number - this widget will span several rows
sticky=NSEW - if cell is larger on which sides will this widget stick to the cell boundary
"""
self._last_geometry_manager_call = {"function": super().grid, "kwargs": kwargs}
return super().grid(**self._apply_argument_scaling(kwargs))
def grid_forget(self):
""" Unmap this widget. """
self._last_geometry_manager_call = None
return super().grid_forget()
def _apply_argument_scaling(self, kwargs: dict) -> dict:
scaled_kwargs = copy.copy(kwargs)
if "pady" in scaled_kwargs:
if isinstance(scaled_kwargs["pady"], (int, float, str)):
scaled_kwargs["pady"] = self._apply_spacing_scaling(scaled_kwargs["pady"])
elif isinstance(scaled_kwargs["pady"], tuple):
scaled_kwargs["pady"] = tuple([self._apply_spacing_scaling(v) for v in scaled_kwargs["pady"]])
if "padx" in kwargs:
if isinstance(scaled_kwargs["padx"], (int, float, str)):
scaled_kwargs["padx"] = self._apply_spacing_scaling(scaled_kwargs["padx"])
elif isinstance(scaled_kwargs["padx"], tuple):
scaled_kwargs["padx"] = tuple([self._apply_spacing_scaling(v) for v in scaled_kwargs["padx"]])
if "x" in scaled_kwargs:
scaled_kwargs["x"] = self._apply_spacing_scaling(scaled_kwargs["x"])
if "y" in scaled_kwargs:
scaled_kwargs["y"] = self._apply_spacing_scaling(scaled_kwargs["y"])
return scaled_kwargs
def _draw(self, no_color_updates: bool = False): def _draw(self, no_color_updates: bool = False):
""" abstract of draw method to be overridden """ """ abstract of draw method to be overridden """
pass pass
@@ -207,7 +97,13 @@ class CTkBaseClass(tkinter.Frame):
raise AttributeError("'config' is not implemented for CTk widgets. For consistency, always use 'configure' instead.") raise AttributeError("'config' is not implemented for CTk widgets. For consistency, always use 'configure' instead.")
def configure(self, require_redraw=False, **kwargs): def configure(self, require_redraw=False, **kwargs):
""" basic configure with bg_color support, calls configure of tkinter.Frame, updates in the end """ """ basic configure with bg_color, width, height support, calls configure of tkinter.Frame, updates in the end """
if "width" in kwargs:
self._set_dimensions(width=kwargs.pop("width"))
if "height" in kwargs:
self._set_dimensions(height=kwargs.pop("height"))
if "bg_color" in kwargs: if "bg_color" in kwargs:
new_bg_color = kwargs.pop("bg_color") new_bg_color = kwargs.pop("bg_color")
@@ -240,6 +136,18 @@ class CTkBaseClass(tkinter.Frame):
else: else:
raise ValueError(f"'{attribute_name}' is not a supported argument. Look at the documentation for supported arguments.") raise ValueError(f"'{attribute_name}' is not a supported argument. Look at the documentation for supported arguments.")
@staticmethod
def _check_kwargs_empty(kwargs_dict, raise_error=False) -> bool:
""" returns True if kwargs are empty, False otherwise, raises error if not empty """
if len(kwargs_dict) > 0:
if raise_error:
raise ValueError(f"{list(kwargs_dict.keys())} are not supported arguments. Look at the documentation for supported arguments.")
else:
return True
else:
return False
def _update_dimensions_event(self, event): def _update_dimensions_event(self, event):
# only redraw if dimensions changed (for performance), independent of scaling # only redraw if dimensions changed (for performance), independent of scaling
if round(self._current_width) != round(event.width / self._widget_scaling) or round(self._current_height) != round(event.height / self._widget_scaling): if round(self._current_width) != round(event.width / self._widget_scaling) or round(self._current_height) != round(event.height / self._widget_scaling):
@@ -336,3 +244,101 @@ class CTkBaseClass(tkinter.Frame):
else: else:
return font return font
def _apply_argument_scaling(self, kwargs: dict) -> dict:
scaled_kwargs = copy.copy(kwargs)
if "pady" in scaled_kwargs:
if isinstance(scaled_kwargs["pady"], (int, float, str)):
scaled_kwargs["pady"] = self._apply_spacing_scaling(scaled_kwargs["pady"])
elif isinstance(scaled_kwargs["pady"], tuple):
scaled_kwargs["pady"] = tuple([self._apply_spacing_scaling(v) for v in scaled_kwargs["pady"]])
if "padx" in kwargs:
if isinstance(scaled_kwargs["padx"], (int, float, str)):
scaled_kwargs["padx"] = self._apply_spacing_scaling(scaled_kwargs["padx"])
elif isinstance(scaled_kwargs["padx"], tuple):
scaled_kwargs["padx"] = tuple([self._apply_spacing_scaling(v) for v in scaled_kwargs["padx"]])
if "x" in scaled_kwargs:
scaled_kwargs["x"] = self._apply_spacing_scaling(scaled_kwargs["x"])
if "y" in scaled_kwargs:
scaled_kwargs["y"] = self._apply_spacing_scaling(scaled_kwargs["y"])
return scaled_kwargs
def destroy(self):
""" Destroy this and all descendants widgets. """
AppearanceModeTracker.remove(self._set_appearance_mode)
ScalingTracker.remove_widget(self._set_scaling, self)
super().destroy()
def place(self, **kwargs):
"""
Place a widget in the parent widget. Use as options:
in=master - master relative to which the widget is placed
in_=master - see 'in' option description
x=amount - locate anchor of this widget at position x of master
y=amount - locate anchor of this widget at position y of master
relx=amount - locate anchor of this widget between 0.0 and 1.0 relative to width of master (1.0 is right edge)
rely=amount - locate anchor of this widget between 0.0 and 1.0 relative to height of master (1.0 is bottom edge)
anchor=NSEW (or subset) - position anchor according to given direction
width=amount - width of this widget in pixel
height=amount - height of this widget in pixel
relwidth=amount - width of this widget between 0.0 and 1.0 relative to width of master (1.0 is the same width as the master)
relheight=amount - height of this widget between 0.0 and 1.0 relative to height of master (1.0 is the same height as the master)
bordermode="inside" or "outside" - whether to take border width of master widget into account
"""
self._last_geometry_manager_call = {"function": super().place, "kwargs": kwargs}
return super().place(**self._apply_argument_scaling(kwargs))
def place_forget(self):
""" Unmap this widget. """
self._last_geometry_manager_call = None
return super().place_forget()
def pack(self, **kwargs):
"""
Pack a widget in the parent widget. Use as options:
after=widget - pack it after you have packed widget
anchor=NSEW (or subset) - position widget according to given direction
before=widget - pack it before you will pack widget
expand=bool - expand widget if parent size grows
fill=NONE or X or Y or BOTH - fill widget if widget grows
in=master - use master to contain this widget
in_=master - see 'in' option description
ipadx=amount - add internal padding in x direction
ipady=amount - add internal padding in y direction
padx=amount - add padding in x direction
pady=amount - add padding in y direction
side=TOP or BOTTOM or LEFT or RIGHT - where to add this widget.
"""
self._last_geometry_manager_call = {"function": super().pack, "kwargs": kwargs}
return super().pack(**self._apply_argument_scaling(kwargs))
def pack_forget(self):
""" Unmap this widget and do not use it for the packing order. """
self._last_geometry_manager_call = None
return super().pack_forget()
def grid(self, **kwargs):
"""
Position a widget in the parent widget in a grid. Use as options:
column=number - use cell identified with given column (starting with 0)
columnspan=number - this widget will span several columns
in=master - use master to contain this widget
in_=master - see 'in' option description
ipadx=amount - add internal padding in x direction
ipady=amount - add internal padding in y direction
padx=amount - add padding in x direction
pady=amount - add padding in y direction
row=number - use cell identified with given row (starting with 0)
rowspan=number - this widget will span several rows
sticky=NSEW - if cell is larger on which sides will this widget stick to the cell boundary
"""
self._last_geometry_manager_call = {"function": super().grid, "kwargs": kwargs}
return super().grid(**self._apply_argument_scaling(kwargs))
def grid_forget(self):
""" Unmap this widget. """
self._last_geometry_manager_call = None
return super().grid_forget()

View File

@@ -75,4 +75,7 @@ seg_7.pack(padx=20, pady=20)
seg_7.configure(state="disabled") seg_7.configure(state="disabled")
seg_7.set("2") seg_7.set("2")
seg_7.configure(height=40, width=400,
dynamic_resizing=False, font=("Times", -20))
app.mainloop() app.mainloop()