diff --git a/Doc/library/tkinter.rst b/Doc/library/tkinter.rst index b0421721bf8d7e5..3d8983c57a12bf0 100644 --- a/Doc/library/tkinter.rst +++ b/Doc/library/tkinter.rst @@ -5475,6 +5475,20 @@ Widget classes inserted or deleted. Otherwise set the flag to the boolean *arg*. + .. method:: edit_canundo() + + Return ``True`` if there is an edit action on the undo stack that can be + undone, and ``False`` otherwise. + + .. versionadded:: next + + .. method:: edit_canredo() + + Return ``True`` if there is an edit action on the redo stack that can be + reapplied, and ``False`` otherwise. + + .. versionadded:: next + .. method:: edit_undo() Undo the most recent edit action, that is, all the inserts and deletes diff --git a/Doc/whatsnew/3.16.rst b/Doc/whatsnew/3.16.rst index 0a110795f371eb7..2b6f396bdf16dd9 100644 --- a/Doc/whatsnew/3.16.rst +++ b/Doc/whatsnew/3.16.rst @@ -144,6 +144,14 @@ shlex a string, even if it is already safe for a shell without being quoted. (Contributed by Jay Berry in :gh:`148846`.) +tkinter +------- + +* Added new :class:`!tkinter.Text` methods :meth:`~tkinter.Text.edit_canundo` + and :meth:`~tkinter.Text.edit_canredo` which return whether an undo or redo + is possible. + (Contributed by Serhiy Storchaka in :gh:`151674`.) + xml --- diff --git a/Lib/test/test_tkinter/test_text.py b/Lib/test/test_tkinter/test_text.py index 0303c2ac1ed1dab..0279198b179404f 100644 --- a/Lib/test/test_tkinter/test_text.py +++ b/Lib/test/test_tkinter/test_text.py @@ -306,6 +306,29 @@ def test_edit_undo_redo(self): text.edit_reset() self.assertRaises(TclError, text.edit_undo) + def test_edit_canundo_canredo(self): + text = self.text + text.configure(undo=True) + + self.assertIs(text.edit_canundo(), False) + self.assertIs(text.edit_canredo(), False) + + text.insert('1.0', 'spam') + self.assertIs(text.edit_canundo(), True) + self.assertIs(text.edit_canredo(), False) + + text.edit_undo() + self.assertIs(text.edit_canundo(), False) + self.assertIs(text.edit_canredo(), True) + + text.edit_redo() + self.assertIs(text.edit_canundo(), True) + self.assertIs(text.edit_canredo(), False) + + text.edit_reset() + self.assertIs(text.edit_canundo(), False) + self.assertIs(text.edit_canredo(), False) + def test_dump(self): text = self.text text.insert('1.0', 'hello') diff --git a/Lib/tkinter/__init__.py b/Lib/tkinter/__init__.py index ba8365f56c37a70..559fe87ed46193b 100644 --- a/Lib/tkinter/__init__.py +++ b/Lib/tkinter/__init__.py @@ -3970,6 +3970,22 @@ def edit(self, *args): """ return self.tk.call(self._w, 'edit', *args) + def edit_canredo(self): + """Return whether redo is possible. + + Return True if redo is possible, i.e. when the redo stack is + not empty, and False otherwise. + """ + return self.tk.getboolean(self.edit("canredo")) + + def edit_canundo(self): + """Return whether undo is possible. + + Return True if undo is possible, i.e. when the undo stack is + not empty, and False otherwise. + """ + return self.tk.getboolean(self.edit("canundo")) + def edit_modified(self, arg=None): """Get or Set the modified flag diff --git a/Misc/NEWS.d/next/Library/2026-06-19-12-00-00.gh-issue-151674.FCYTvs.rst b/Misc/NEWS.d/next/Library/2026-06-19-12-00-00.gh-issue-151674.FCYTvs.rst new file mode 100644 index 000000000000000..84e21d4cbc4bd72 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-06-19-12-00-00.gh-issue-151674.FCYTvs.rst @@ -0,0 +1,3 @@ +Add the :meth:`~tkinter.Text.edit_canundo` and :meth:`~tkinter.Text.edit_canredo` +methods of :class:`!tkinter.Text`, wrapping the Tk ``edit canundo`` and +``edit canredo`` subcommands.