Skip to content

Commit 487ae5b

Browse files
gh-151675: Add tkinter Text.sync() and Text.pendingsync()
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 bfecfcc commit 487ae5b

5 files changed

Lines changed: 84 additions & 0 deletions

File tree

Doc/library/tkinter.rst

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

55955595
.. versionadded:: 3.3
55965596

5597+
.. method:: sync(command=None)
5598+
5599+
Control the synchronization of the displayed view with the underlying
5600+
text, which may lag behind when line heights have not yet been computed
5601+
(for example, for lines that have never been displayed).
5602+
If *command* is omitted, bring the line metrics up to date immediately by
5603+
forcing computation of any outdated line heights, and return once they
5604+
are current.
5605+
Otherwise schedule *command* to be called, with no arguments, exactly
5606+
once as soon as all line heights are up to date; if there are no pending
5607+
calculations, it is called immediately.
5608+
5609+
.. versionadded:: next
5610+
5611+
.. method:: pendingsync()
5612+
5613+
Return ``True`` if the line height calculations are not up to date, and
5614+
``False`` otherwise.
5615+
The ``<<WidgetViewSync>>`` virtual event fires whenever this state
5616+
changes, with the *detail* field set to the new value.
5617+
5618+
.. versionadded:: next
5619+
55975620
.. method:: yview_pickplace(*what)
55985621

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

Doc/whatsnew/3.16.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,14 @@ shlex
138138
a string, even if it is already safe for a shell without being quoted.
139139
(Contributed by Jay Berry in :gh:`148846`.)
140140

141+
tkinter
142+
-------
143+
144+
* Added new :class:`!tkinter.Text` methods :meth:`~tkinter.Text.sync` and
145+
:meth:`~tkinter.Text.pendingsync` which control and report the
146+
synchronization of the displayed view with the underlying text.
147+
(Contributed by Serhiy Storchaka in :gh:`151675`.)
148+
141149
xml
142150
---
143151

Lib/test/test_tkinter/test_text.py

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

28+
def test_sync(self):
29+
text = self.text
30+
# sync() returns None and brings line metrics up to date.
31+
self.assertIsNone(text.sync())
32+
self.assertIs(text.pendingsync(), False)
33+
34+
# sync(command) schedules a one-shot callback.
35+
events = []
36+
text.sync(command=lambda: events.append('synced'))
37+
text.update()
38+
self.assertEqual(events, ['synced'])
39+
2840
def test_search(self):
2941
text = self.text
3042

Lib/tkinter/__init__.py

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

4097+
def pendingsync(self): # new in Tk 8.5
4098+
"""Return whether the line heights calculations are not up-to-date.
4099+
4100+
Return True if the line heights calculations are not up-to-date,
4101+
and False otherwise.
4102+
"""
4103+
return self.tk.getboolean(self.tk.call(self._w, 'pendingsync'))
4104+
4105+
def sync(self, command=None): # new in Tk 8.5
4106+
"""Control the synchronization of the view of the text widget.
4107+
4108+
If command is not specified, immediately bring the line metrics
4109+
up-to-date by forcing computation of any outdated line heights.
4110+
The command returns immediately if there is no such outdated line.
4111+
4112+
If command is specified, schedule it to be executed (by the event
4113+
loop) exactly once as soon as all line heights are up-to-date.
4114+
If there are no pending line metrics calculations, command is
4115+
executed immediately.
4116+
"""
4117+
if command is None:
4118+
self.tk.call(self._w, 'sync')
4119+
else:
4120+
def callit():
4121+
try:
4122+
command()
4123+
finally:
4124+
try:
4125+
self.deletecommand(name)
4126+
except TclError:
4127+
pass
4128+
try:
4129+
callit.__name__ = command.__name__
4130+
except AttributeError:
4131+
callit.__name__ = type(command).__name__
4132+
name = self._register(callit)
4133+
self.tk.call(self._w, 'sync', '-command', name)
4134+
40974135
def replace(self, index1, index2, chars, *args): # new in Tk 8.5
40984136
"""Replaces the range of characters between index1 and index2 with
40994137
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)