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:
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:
self._background_corner_colors = kwargs.pop("background_corner_colors")
require_redraw = True

View File

@ -225,12 +225,6 @@ class CTkComboBox(CTkBaseClass):
self._variable = kwargs.pop("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:
self._values = kwargs.pop("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))
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:
self._placeholder_text = kwargs.pop("placeholder_text")
if self._placeholder_text_active:

View File

@ -163,12 +163,6 @@ class CTkFrame(CTkBaseClass):
self._border_width = kwargs.pop("border_width")
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)
def cget(self, attribute_name: str) -> any:

View File

@ -145,12 +145,6 @@ class CTkLabel(CTkBaseClass):
self._text_color = kwargs.pop("text_color")
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:
self._corner_radius = kwargs.pop("corner_radius")
text_label_grid_sticky = self._anchor if self._anchor != "center" else ""

View File

@ -244,12 +244,6 @@ class CTkOptionMenu(CTkBaseClass):
else:
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:
self._values = kwargs.pop("values")
self._dropdown_menu.configure(values=self._values)

View File

@ -192,12 +192,6 @@ class CTkProgressBar(CTkBaseClass):
if "indeterminate_speed" in kwargs:
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)
def cget(self, attribute_name: str) -> any:

View File

@ -175,12 +175,6 @@ class CTkScrollbar(CTkBaseClass):
self._border_spacing = kwargs.pop("border_spacing")
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)
def cget(self, attribute_name: str) -> any:

View File

@ -91,6 +91,12 @@ class CTkSegmentedButton(CTkFrame):
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):
if not self._variable_callback_blocked:
self.set(self._variable.get(), from_variable_callback=True)
@ -184,10 +190,6 @@ class CTkSegmentedButton(CTkFrame):
self._configure_button_corners_for_index(index)
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:
super().configure(bg_color=kwargs.pop("bg_color"))

View File

@ -245,12 +245,6 @@ class CTkSlider(CTkBaseClass):
else:
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)
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))
self._canvas.configure(bg=ThemeManager.single_color(self._bg_color, self._appearance_mode))
def configure(self, **kwargs):
return
def tab(self, name: str) -> CTkFrame:
""" 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)
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:
self._font = kwargs.pop("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.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):
""" abstract of draw method to be overridden """
pass
@ -207,7 +97,13 @@ class CTkBaseClass(tkinter.Frame):
raise AttributeError("'config' is not implemented for CTk widgets. For consistency, always use 'configure' instead.")
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:
new_bg_color = kwargs.pop("bg_color")
@ -240,6 +136,18 @@ class CTkBaseClass(tkinter.Frame):
else:
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):
# 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):
@ -336,3 +244,101 @@ class CTkBaseClass(tkinter.Frame):
else:
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.set("2")
seg_7.configure(height=40, width=400,
dynamic_resizing=False, font=("Times", -20))
app.mainloop()