Skip to content

Commit 88e5d8a

Browse files
gh-151675: Add tkinter Text.sync() and Text.pendingsync() (GH-151677)
Wrap the Tk text widget "sync" and "pendingsync" subcommands, which control and report the synchronization of the displayed view with the underlying text when line heights have not yet been computed.
1 parent 706238e commit 88e5d8a

5 files changed

Lines changed: 81 additions & 0 deletions

File tree

Doc/library/tkinter.rst

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5608,6 +5608,29 @@ Widget classes
56085608

56095609
.. versionadded:: 3.3
56105610

5611+
.. method:: sync(command=None)
5612+
5613+
Control the synchronization of the displayed view with the underlying
5614+
text, which may lag behind when line heights have not yet been computed
5615+
(for example, for lines that have never been displayed).
5616+
If *command* is omitted, bring the line metrics up to date immediately by
5617+
forcing computation of any outdated line heights, and return once they
5618+
are current.
5619+
Otherwise schedule *command* to be called, with no arguments, exactly
5620+
once as soon as all line heights are up to date; if there are no pending
5621+
calculations, it is called immediately.
5622+
5623+
.. versionadded:: next
5624+
5625+
.. method:: pendingsync()
5626+
5627+
Return ``True`` if the line height calculations are not up to date, and
5628+
``False`` otherwise.
5629+
The ``<<WidgetViewSync>>`` virtual event fires whenever this state
5630+
changes, with the *detail* field set to the new value.
5631+
5632+
.. versionadded:: next
5633+
56115634
.. method:: yview_pickplace(*what)
56125635

56135636
Adjust the view so that the location given by *what* is visible.

Doc/whatsnew/3.16.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,11 @@ tkinter
152152
is possible.
153153
(Contributed by Serhiy Storchaka in :gh:`151674`.)
154154

155+
* Added new :class:`!tkinter.Text` methods :meth:`~tkinter.Text.sync` and
156+
:meth:`~tkinter.Text.pendingsync` which control and report the
157+
synchronization of the displayed view with the underlying text.
158+
(Contributed by Serhiy Storchaka in :gh:`151675`.)
159+
155160
xml
156161
---
157162

Lib/test/test_tkinter/test_text.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,18 @@ def test_debug(self):
2626
text.debug(olddebug)
2727
self.assertEqual(text.debug(), olddebug)
2828

29+
def test_sync(self):
30+
text = self.text
31+
# sync() returns None and brings line metrics up to date.
32+
self.assertIsNone(text.sync())
33+
self.assertIs(text.pendingsync(), False)
34+
35+
# sync(command) schedules a one-shot callback.
36+
events = []
37+
text.sync(command=lambda: events.append('synced'))
38+
text.update()
39+
self.assertEqual(events, ['synced'])
40+
2941
def test_index(self):
3042
text = self.text
3143
text.insert('1.0', 'Lorem ipsum\ndolor sit amet')

Lib/tkinter/__init__.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4110,6 +4110,44 @@ def peer_names(self): # new in Tk 8.5
41104110
the widget itself)."""
41114111
return self.tk.splitlist(self.tk.call(self._w, 'peer', 'names'))
41124112

4113+
def pendingsync(self): # new in Tk 8.5
4114+
"""Return whether the line heights calculations are not up-to-date.
4115+
4116+
Return True if the line heights calculations are not up-to-date,
4117+
and False otherwise.
4118+
"""
4119+
return self.tk.getboolean(self.tk.call(self._w, 'pendingsync'))
4120+
4121+
def sync(self, command=None): # new in Tk 8.5
4122+
"""Control the synchronization of the view of the text widget.
4123+
4124+
If command is not specified, immediately bring the line metrics
4125+
up-to-date by forcing computation of any outdated line heights.
4126+
The command returns immediately if there is no such outdated line.
4127+
4128+
If command is specified, schedule it to be executed (by the event
4129+
loop) exactly once as soon as all line heights are up-to-date.
4130+
If there are no pending line metrics calculations, command is
4131+
executed immediately.
4132+
"""
4133+
if command is None:
4134+
self.tk.call(self._w, 'sync')
4135+
else:
4136+
def callit():
4137+
try:
4138+
command()
4139+
finally:
4140+
try:
4141+
self.deletecommand(name)
4142+
except TclError:
4143+
pass
4144+
try:
4145+
callit.__name__ = command.__name__
4146+
except AttributeError:
4147+
callit.__name__ = type(command).__name__
4148+
name = self._register(callit)
4149+
self.tk.call(self._w, 'sync', '-command', name)
4150+
41134151
def replace(self, index1, index2, chars, *args): # new in Tk 8.5
41144152
"""Replaces the range of characters between index1 and index2 with
41154153
the given characters and tags specified by args.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Add the :meth:`~tkinter.Text.sync` and :meth:`~tkinter.Text.pendingsync`
2+
methods of :class:`!tkinter.Text`, wrapping the Tk ``sync`` and
3+
``pendingsync`` subcommands.

0 commit comments

Comments
 (0)