[feat] Combobox Validation

Allows for validation of the combobox through the hidden entry widget.
User is able to validate provided that they *do not delete or insert
text*. If the user wishes to do this in validation, they first must
ensure that the customtkinter library does not trigger the call
repeatidly AND should add a short delay (via self.after). This is
because on when `self._entry.insert` is called within customtkinter,
it will clear the `validate` property thus causing future validation
to fail.

Signed off by Trask Crane (hcrane3@gatech.edu)
This commit is contained in:
Crane, Trask 2023-06-11 00:13:20 -04:00
parent 3f4fe4f5ab
commit b8efb9739e

View File

@ -9,6 +9,7 @@ from .theme import ThemeManager
from .core_rendering import DrawEngine from .core_rendering import DrawEngine
from .core_widget_classes import CTkBaseClass from .core_widget_classes import CTkBaseClass
from .font import CTkFont from .font import CTkFont
from .utility import pop_from_dict_by_set
class CTkComboBox(CTkBaseClass): class CTkComboBox(CTkBaseClass):
@ -17,6 +18,9 @@ class CTkComboBox(CTkBaseClass):
For detailed information check out the documentation. For detailed information check out the documentation.
""" """
# attributes that are passed to and managed by the tkinter entry only:
_valid_tk_entry_attributes = {"invalidcommand", "validate", "validatecommand"}
def __init__(self, def __init__(self,
master: any, master: any,
width: int = 140, width: int = 140,
@ -100,7 +104,8 @@ class CTkComboBox(CTkBaseClass):
bd=0, bd=0,
justify=justify, justify=justify,
highlightthickness=0, highlightthickness=0,
font=self._apply_font_scaling(self._font)) font=self._apply_font_scaling(self._font),
**pop_from_dict_by_set(kwargs, self._valid_tk_entry_attributes))
self._create_grid() self._create_grid()
self._create_bindings() self._create_bindings()
@ -295,6 +300,7 @@ class CTkComboBox(CTkBaseClass):
if "justify" in kwargs: if "justify" in kwargs:
self._entry.configure(justify=kwargs.pop("justify")) self._entry.configure(justify=kwargs.pop("justify"))
self._entry.configure(**pop_from_dict_by_set(kwargs, self._valid_tk_entry_attributes)) # configure Tkinter.Entry
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:
@ -338,6 +344,9 @@ class CTkComboBox(CTkBaseClass):
return self._command return self._command
elif attribute_name == "justify": elif attribute_name == "justify":
return self._entry.cget("justify") return self._entry.cget("justify")
elif attribute_name in self._valid_tk_entry_attributes:
return self._entry.cget(attribute_name) # cget of tkinter.Entry
else: else:
return super().cget(attribute_name) return super().cget(attribute_name)
@ -393,6 +402,9 @@ class CTkComboBox(CTkBaseClass):
self._entry.delete(0, tkinter.END) self._entry.delete(0, tkinter.END)
self._entry.insert(0, value) self._entry.insert(0, value)
def delete(self, start, end):
self._entry.delete(start, end)
def get(self) -> str: def get(self) -> str:
return self._entry.get() return self._entry.get()