diff --git a/Doc/library/tkinter.rst b/Doc/library/tkinter.rst index 249b1602a711ad..13fe3514b5ebc8 100644 --- a/Doc/library/tkinter.rst +++ b/Doc/library/tkinter.rst @@ -4254,6 +4254,14 @@ Widget classes Typically associated with mouse motion events, to produce the effect of dragging the entry at high speed through the window. + .. method:: validate() + + Force an evaluation of the command given by the *validatecommand* option, + independently of the conditions specified by the *validate* option, and + return whether the value is considered valid. + + .. versionadded:: next + .. class:: Frame(master=None, cnf={}, **kw) @@ -5206,6 +5214,14 @@ Widget classes .. versionadded:: 3.8 + .. method:: validate() + + Force an evaluation of the command given by the *validatecommand* option, + independently of the conditions specified by the *validate* option, and + return whether the value is considered valid. + + .. versionadded:: next + .. class:: Text(master=None, cnf={}, **kw) diff --git a/Doc/whatsnew/3.16.rst b/Doc/whatsnew/3.16.rst index 8abc4d0af8d19f..3c625801c46a1c 100644 --- a/Doc/whatsnew/3.16.rst +++ b/Doc/whatsnew/3.16.rst @@ -163,6 +163,11 @@ tkinter synchronization of the displayed view with the underlying text. (Contributed by Serhiy Storchaka in :gh:`151675`.) +* Added a :meth:`!validate` method to the :class:`!tkinter.Entry` and + :class:`!tkinter.Spinbox` widgets, which forces an evaluation of the + validation command. + (Contributed by Serhiy Storchaka in :gh:`151878`.) + * Added new window-management methods :meth:`~tkinter.Misc.winfo_isdark` (dark mode detection), :meth:`~tkinter.Wm.wm_iconbadge` (application icon badge) and :meth:`~tkinter.Wm.wm_stackorder` (toplevel stacking order). diff --git a/Lib/test/test_tkinter/test_widgets.py b/Lib/test/test_tkinter/test_widgets.py index 4b51d219d87e5b..d0305562a0cb05 100644 --- a/Lib/test/test_tkinter/test_widgets.py +++ b/Lib/test/test_tkinter/test_widgets.py @@ -589,6 +589,25 @@ def test_select_aliases(self): self.assertRaisesRegex(TclError, 'bad entry index "xyz"', widget.select_range, 'xyz', 'end') + def test_validate(self): + calls = [] + def validatecommand(value): + calls.append(value) + return value.isdigit() + # validate='none' means validation is never triggered automatically, + # so validate() exercises the forced evaluation. + widget = self.create(validate='none', + validatecommand=(self.root.register(validatecommand), '%P')) + widget.insert(0, '123') + result = widget.validate() + self.assertIs(result, True) + self.assertEqual(calls, ['123']) + widget.delete(0, 'end') + widget.insert(0, 'abc') + calls.clear() + self.assertIs(widget.validate(), False) + self.assertEqual(calls, ['abc']) + @add_configure_tests(StandardOptionsTests) class SpinboxTest(EntryTest, unittest.TestCase): diff --git a/Lib/tkinter/__init__.py b/Lib/tkinter/__init__.py index 68de4a35689691..974e386be1bb49 100644 --- a/Lib/tkinter/__init__.py +++ b/Lib/tkinter/__init__.py @@ -3445,6 +3445,14 @@ def selection_to(self, index): select_to = selection_to + def validate(self): + """Force an evaluation of the validation command. + + This evaluates the command given by the validatecommand option, + independently of the conditions specified by the validate option. + Return whether the value is considered valid.""" + return self.tk.getboolean(self.tk.call(self._w, 'validate')) + class Frame(Widget): """Frame widget which may contain other widgets and can have a 3D border.""" @@ -4957,6 +4965,14 @@ def selection_to(self, index): """Set the variable end of a selection to INDEX.""" self.selection('to', index) + def validate(self): + """Force an evaluation of the validation command. + + This evaluates the command given by the validatecommand option, + independently of the conditions specified by the validate option. + Return whether the value is considered valid.""" + return self.tk.getboolean(self.tk.call(self._w, 'validate')) + ########################################################################### diff --git a/Misc/NEWS.d/next/Library/2026-06-22-01-02-33.gh-issue-151878.IFIA5C.rst b/Misc/NEWS.d/next/Library/2026-06-22-01-02-33.gh-issue-151878.IFIA5C.rst new file mode 100644 index 00000000000000..af0d2c25136c45 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-06-22-01-02-33.gh-issue-151878.IFIA5C.rst @@ -0,0 +1,3 @@ +Add the :meth:`!validate` method to the :class:`tkinter.Entry` and +:class:`tkinter.Spinbox` widgets, forcing an evaluation of the validation +command.