diff --git a/customtkinter/widgets/ctk_button.py b/customtkinter/widgets/ctk_button.py index 9b97ba2..da9c56a 100644 --- a/customtkinter/widgets/ctk_button.py +++ b/customtkinter/widgets/ctk_button.py @@ -408,3 +408,7 @@ class CTkButton(CTkBaseClass): self.after(100, self._click_animation) self._command() + + def bind(self, sequence=None, command=None, add=None): + """ called on the tkinter.Canvas """ + return self._canvas.bind(sequence, command, add) diff --git a/customtkinter/widgets/ctk_checkbox.py b/customtkinter/widgets/ctk_checkbox.py index ec2759f..7dfe654 100644 --- a/customtkinter/widgets/ctk_checkbox.py +++ b/customtkinter/widgets/ctk_checkbox.py @@ -363,3 +363,7 @@ class CTkCheckBox(CTkBaseClass): def get(self) -> Union[int, str]: return self._onvalue if self._check_state is True else self._offvalue + + def bind(self, sequence=None, command=None, add=None): + """ called on the tkinter.Canvas """ + return self._canvas.bind(sequence, command, add) diff --git a/customtkinter/widgets/ctk_combobox.py b/customtkinter/widgets/ctk_combobox.py index efb7b58..790a1f7 100644 --- a/customtkinter/widgets/ctk_combobox.py +++ b/customtkinter/widgets/ctk_combobox.py @@ -349,3 +349,7 @@ class CTkComboBox(CTkBaseClass): def _clicked(self, event=0): if self._state is not tkinter.DISABLED and len(self._values) > 0: self._open_dropdown_menu() + + def bind(self, sequence=None, command=None, add=None): + """ called on the tkinter.Canvas """ + return self._canvas.bind(sequence, command, add) diff --git a/customtkinter/widgets/ctk_entry.py b/customtkinter/widgets/ctk_entry.py index 3ebac0e..bbf1cce 100644 --- a/customtkinter/widgets/ctk_entry.py +++ b/customtkinter/widgets/ctk_entry.py @@ -89,10 +89,12 @@ class CTkEntry(CTkBaseClass): textvariable=self._textvariable, **pop_from_dict_by_set(kwargs, self._valid_tk_entry_attributes)) if self._corner_radius >= self._minimum_x_padding: - self._entry.grid(column=0, row=0, sticky="nswe", padx=min(self._apply_widget_scaling(self._corner_radius), self._current_height), + self._entry.grid(column=0, row=0, sticky="nswe", + padx=min(self._apply_widget_scaling(self._corner_radius), round(self._apply_widget_scaling(self._current_height/2))), pady=(self._apply_widget_scaling(self._border_width), self._apply_widget_scaling(self._border_width + 1))) else: - self._entry.grid(column=0, row=0, sticky="nswe", padx=self._apply_widget_scaling(self._minimum_x_padding), + self._entry.grid(column=0, row=0, sticky="nswe", + padx=self._apply_widget_scaling(self._minimum_x_padding), pady=(self._apply_widget_scaling(self._border_width), self._apply_widget_scaling(self._border_width + 1))) self._check_kwargs_empty(kwargs, raise_error=True) @@ -186,9 +188,11 @@ class CTkEntry(CTkBaseClass): if "corner_radius" in kwargs: self._corner_radius = kwargs.pop("corner_radius") if self._corner_radius >= self._minimum_x_padding: - self._entry.grid(column=0, row=0, sticky="we", padx=min(self._apply_widget_scaling(self._corner_radius), self._current_height / 2)) + self._entry.grid(column=0, row=0, sticky="we", + padx=min(self._apply_widget_scaling(self._corner_radius), round(self._apply_widget_scaling(self._current_height/2)))) else: - self._entry.grid(column=0, row=0, sticky="we", padx=self._apply_widget_scaling(self._minimum_x_padding)) + self._entry.grid(column=0, row=0, sticky="we", + padx=self._apply_widget_scaling(self._minimum_x_padding)) require_redraw = True if "width" in kwargs: @@ -253,10 +257,11 @@ class CTkEntry(CTkBaseClass): elif attribute_name in self._valid_tk_entry_attributes: return self._entry.cget(attribute_name) # cget of tkinter.Entry else: - return super().cget(attribute_name) + return super().cget(attribute_name) # cget of CTkBaseClass def bind(self, sequence=None, command=None, add=None): - self._entry.bind(sequence, command, add) + """ called on the tkinter.Entry """ + return self._entry.bind(sequence, command, add) def _activate_placeholder(self): if self._entry.get() == "" and self._placeholder_text is not None and (self._textvariable is None or self._textvariable == ""): diff --git a/customtkinter/widgets/ctk_frame.py b/customtkinter/widgets/ctk_frame.py index 0fe4f3e..4fa5cf2 100644 --- a/customtkinter/widgets/ctk_frame.py +++ b/customtkinter/widgets/ctk_frame.py @@ -154,5 +154,10 @@ class CTkFrame(CTkBaseClass): return self._fg_color elif attribute_name == "border_color": return self._border_color + else: return super().cget(attribute_name) + + def bind(self, sequence=None, command=None, add=None): + """ called on the tkinter.Canvas """ + return self._canvas.bind(sequence, command, add) diff --git a/customtkinter/widgets/ctk_label.py b/customtkinter/widgets/ctk_label.py index e9cf1c5..25b501c 100644 --- a/customtkinter/widgets/ctk_label.py +++ b/customtkinter/widgets/ctk_label.py @@ -6,6 +6,8 @@ from ..theme_manager import ThemeManager from ..draw_engine import DrawEngine from .widget_base_class import CTkBaseClass +from .widget_helper_functions import pop_from_dict_by_set + class CTkLabel(CTkBaseClass): """ @@ -14,7 +16,8 @@ class CTkLabel(CTkBaseClass): """ # attributes that are passed to and managed by the tkinter entry only: - _valid_tk_label_attributes = {"compound", "cursor", ""} + _valid_tk_label_attributes = {"compound", "cursor", "image", "justify", "padx", "pady", + "textvariable", "state", "takefocus", "underline", "wraplength"} def __init__(self, *args, width: int = 140, @@ -65,10 +68,13 @@ class CTkLabel(CTkBaseClass): anchor=self._anchor, text=self._text, font=self._apply_font_scaling(self._font), - **kwargs) + **pop_from_dict_by_set(kwargs, self._valid_tk_label_attributes)) + text_label_grid_sticky = self._anchor if self._anchor != "center" else "" - self._text_label.grid(row=0, column=0, padx=self._apply_widget_scaling(self._corner_radius), - sticky=text_label_grid_sticky) + self._text_label.grid(row=0, column=0, sticky=text_label_grid_sticky, + padx=min(self._apply_widget_scaling(self._corner_radius), round(self._current_height/2))) + + self._check_kwargs_empty(kwargs, raise_error=True) self.bind('', self._update_dimensions_event) self._draw() @@ -78,9 +84,10 @@ class CTkLabel(CTkBaseClass): self._canvas.configure(width=self._apply_widget_scaling(self._desired_width), height=self._apply_widget_scaling(self._desired_height)) self._text_label.configure(font=self._apply_font_scaling(self._font)) + text_label_grid_sticky = self._anchor if self._anchor != "center" else "" - self._text_label.grid(row=0, column=0, padx=self._apply_widget_scaling(self._corner_radius), - sticky=text_label_grid_sticky) + self._text_label.grid(row=0, column=0, sticky=text_label_grid_sticky, + padx=min(self._apply_widget_scaling(self._corner_radius), round(self._current_height/2))) self._draw() @@ -119,8 +126,8 @@ class CTkLabel(CTkBaseClass): if "anchor" in kwargs: self._anchor = kwargs.pop("anchor") text_label_grid_sticky = self._anchor if self._anchor != "center" else "" - self._text_label.grid(row=0, column=0, padx=self._apply_widget_scaling(self._corner_radius), - sticky=text_label_grid_sticky) + self._text_label.grid(row=0, column=0, sticky=text_label_grid_sticky, + padx=min(self._apply_widget_scaling(self._corner_radius), round(self._current_height/2))) if "text" in kwargs: self._text = kwargs.pop("text") @@ -144,12 +151,15 @@ class CTkLabel(CTkBaseClass): if "height" in kwargs: self._set_dimensions(height=kwargs.pop("height")) - if "_bg_color" in kwargs: - super().configure(bg_color=kwargs.pop("_bg_color"), require_redraw=require_redraw) - else: - super().configure(require_redraw=require_redraw) + if "corner_radius" in kwargs: + self._corner_radius = kwargs.pop("corner_radius") + text_label_grid_sticky = self._anchor if self._anchor != "center" else "" + self._text_label.grid(row=0, column=0, sticky=text_label_grid_sticky, + padx=min(self._apply_widget_scaling(self._corner_radius), round(self._current_height/2))) + require_redraw = True - self._text_label.configure(**kwargs) # pass remaining kwargs to label + self._text_label.configure(**pop_from_dict_by_set(kwargs, self._valid_tk_label_attributes)) # configure tkinter.Label + super().configure(require_redraw=require_redraw, **kwargs) # configure CTkBaseClass def cget(self, attribute_name: str) -> any: if attribute_name == "corner_radius": @@ -166,5 +176,12 @@ class CTkLabel(CTkBaseClass): return self._font elif attribute_name == "anchor": return self._anchor + + elif attribute_name in self._valid_tk_label_attributes: + return self._text_label.cget(attribute_name) # cget of tkinter.Label else: - return super().cget(attribute_name) + return super().cget(attribute_name) # cget of CTkBaseClass + + def bind(self, sequence=None, command=None, add=None): + """ called on the tkinter.Label """ + return self._text_label.bind(sequence, command, add) diff --git a/customtkinter/widgets/ctk_optionmenu.py b/customtkinter/widgets/ctk_optionmenu.py index 34f9aae..0dabe7f 100644 --- a/customtkinter/widgets/ctk_optionmenu.py +++ b/customtkinter/widgets/ctk_optionmenu.py @@ -356,3 +356,7 @@ class CTkOptionMenu(CTkBaseClass): def _clicked(self, event=0): if self._state is not tkinter.DISABLED and len(self._values) > 0: self._open_dropdown_menu() + + def bind(self, sequence=None, command=None, add=None): + """ called on the tkinter.Canvas """ + return self._canvas.bind(sequence, command, add) diff --git a/customtkinter/widgets/ctk_progressbar.py b/customtkinter/widgets/ctk_progressbar.py index b59c112..9d19679 100644 --- a/customtkinter/widgets/ctk_progressbar.py +++ b/customtkinter/widgets/ctk_progressbar.py @@ -281,3 +281,7 @@ class CTkProgressBar(CTkBaseClass): else: self._indeterminate_value += self._indeterminate_speed self._draw() + + def bind(self, sequence=None, command=None, add=None): + """ called on the tkinter.Canvas """ + return self._canvas.bind(sequence, command, add) diff --git a/customtkinter/widgets/ctk_radiobutton.py b/customtkinter/widgets/ctk_radiobutton.py index 00b8faa..e547ab8 100644 --- a/customtkinter/widgets/ctk_radiobutton.py +++ b/customtkinter/widgets/ctk_radiobutton.py @@ -324,3 +324,7 @@ class CTkRadioButton(CTkBaseClass): self._variable_callback_blocked = True self._variable.set("") self._variable_callback_blocked = False + + def bind(self, sequence=None, command=None, add=None): + """ called on the tkinter.Canvas """ + return self._canvas.bind(sequence, command, add) diff --git a/customtkinter/widgets/ctk_scrollbar.py b/customtkinter/widgets/ctk_scrollbar.py index 6b31e44..201a527 100644 --- a/customtkinter/widgets/ctk_scrollbar.py +++ b/customtkinter/widgets/ctk_scrollbar.py @@ -248,3 +248,7 @@ class CTkScrollbar(CTkBaseClass): def get(self): return self._start_value, self._end_value + + def bind(self, sequence=None, command=None, add=None): + """ called on the tkinter.Canvas """ + return self._canvas.bind(sequence, command, add) diff --git a/customtkinter/widgets/ctk_slider.py b/customtkinter/widgets/ctk_slider.py index 186b81c..ade50d4 100644 --- a/customtkinter/widgets/ctk_slider.py +++ b/customtkinter/widgets/ctk_slider.py @@ -364,3 +364,7 @@ class CTkSlider(CTkBaseClass): def _variable_callback(self, var_name, index, mode): if not self._variable_callback_blocked: self.set(self._variable.get(), from_variable_callback=True) + + def bind(self, sequence=None, command=None, add=None): + """ called on the tkinter.Canvas """ + return self._canvas.bind(sequence, command, add) diff --git a/customtkinter/widgets/ctk_switch.py b/customtkinter/widgets/ctk_switch.py index f76e929..3b7c37a 100644 --- a/customtkinter/widgets/ctk_switch.py +++ b/customtkinter/widgets/ctk_switch.py @@ -373,3 +373,7 @@ class CTkSwitch(CTkBaseClass): self.select(from_variable_callback=True) elif self._variable.get() == self._offvalue: self.deselect(from_variable_callback=True) + + def bind(self, sequence=None, command=None, add=None): + """ called on the tkinter.Canvas """ + return self._canvas.bind(sequence, command, add) diff --git a/customtkinter/widgets/ctk_textbox.py b/customtkinter/widgets/ctk_textbox.py index fae123c..4aad34f 100644 --- a/customtkinter/widgets/ctk_textbox.py +++ b/customtkinter/widgets/ctk_textbox.py @@ -178,6 +178,10 @@ class CTkTextbox(CTkBaseClass): else: return super().cget(attribute_name) + def bind(self, sequence=None, command=None, add=None): + """ called on the tkinter.Text """ + return self._textbox.bind(sequence, command, add) + def yview(self, *args): return self._textbox.yview(*args)