From: Serhiy Storchaka Date: Fri, 10 Jul 2026 17:16:53 +0000 (+0300) Subject: gh-59396: Add use_ttk parameter to tkinter ScrolledText (GH-153119) X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=fbce45b58711e9d02d270db2cd72a38dcbb345de;p=thirdparty%2FPython%2Fcpython.git gh-59396: Add use_ttk parameter to tkinter ScrolledText (GH-153119) ScrolledText gained a keyword-only use_ttk parameter to build the surrounding frame and the vertical scroll bar from the themed tkinter.ttk widgets instead of the classic tkinter widgets. The classic widgets remain the default. Co-authored-by: Claude Opus 4.8 --- diff --git a/Doc/library/tkinter.scrolledtext.rst b/Doc/library/tkinter.scrolledtext.rst index 30aef8748edb..2b147873cc23 100644 --- a/Doc/library/tkinter.scrolledtext.rst +++ b/Doc/library/tkinter.scrolledtext.rst @@ -23,7 +23,16 @@ most normal geometry management behavior. Should more specific control be necessary, the following attributes are available: -.. class:: ScrolledText(master=None, **kw) +.. class:: ScrolledText(master=None, *, use_ttk=False, **kw) + + The keyword arguments are passed to the :class:`~tkinter.Text` widget. + + When *use_ttk* is true, the surrounding frame and the scroll bar are the + themed :mod:`tkinter.ttk` widgets; + the default is the classic :mod:`tkinter` widgets. + + .. versionchanged:: next + Added the *use_ttk* parameter. .. attribute:: frame diff --git a/Doc/whatsnew/3.16.rst b/Doc/whatsnew/3.16.rst index 06c3dbb2f0f1..7cf1ad7ae298 100644 --- a/Doc/whatsnew/3.16.rst +++ b/Doc/whatsnew/3.16.rst @@ -456,6 +456,11 @@ tkinter them. (Contributed by Serhiy Storchaka in :gh:`59396`.) +* :class:`tkinter.scrolledtext.ScrolledText` gained a *use_ttk* parameter to use + the themed :mod:`tkinter.ttk` frame and scroll bar instead of the classic + :mod:`tkinter` widgets. + (Contributed by Serhiy Storchaka in :gh:`59396`.) + * :class:`tkinter.font.Font` can now wrap a font description without creating a new named font, by passing it as *font* with ``exists=True`` and no *name*. This avoids a loss of precision in :meth:`~tkinter.font.Font.actual`, diff --git a/Lib/test/test_tkinter/test_scrolledtext.py b/Lib/test/test_tkinter/test_scrolledtext.py index 913e7d8aab6c..ea4789771bb0 100644 --- a/Lib/test/test_tkinter/test_scrolledtext.py +++ b/Lib/test/test_tkinter/test_scrolledtext.py @@ -1,5 +1,6 @@ import unittest import tkinter +from tkinter import ttk from tkinter.scrolledtext import ScrolledText from test.support import requires from test.test_tkinter.support import setUpModule # noqa: F401 @@ -19,8 +20,11 @@ class ScrolledTextTest(AbstractTkTest, unittest.TestCase): st = self.create(background='red', height=5) # It is a Text widget held in a Frame together with a Scrollbar. self.assertIsInstance(st, tkinter.Text) + # By default the frame and scroll bar are the classic tkinter widgets. self.assertIsInstance(st.frame, tkinter.Frame) + self.assertNotIsInstance(st.frame, ttk.Frame) self.assertIsInstance(st.vbar, tkinter.Scrollbar) + self.assertNotIsInstance(st.vbar, ttk.Scrollbar) self.assertEqual(st.winfo_parent(), str(st.frame)) # str() returns the frame, so that geometry managers manage it. self.assertEqual(str(st), str(st.frame)) @@ -28,6 +32,12 @@ class ScrolledTextTest(AbstractTkTest, unittest.TestCase): self.assertEqual(str(st['background']), 'red') self.assertEqual(st['height'], 5 if self.wantobjects else '5') + def test_use_ttk(self): + # use_ttk=True uses the themed tkinter.ttk widgets. + st = self.create(use_ttk=True) + self.assertIsInstance(st.frame, ttk.Frame) + self.assertIsInstance(st.vbar, ttk.Scrollbar) + def test_text_methods(self): st = self.create() st.insert('1.0', 'hello\nworld') diff --git a/Lib/tkinter/scrolledtext.py b/Lib/tkinter/scrolledtext.py index 8dcead5e3193..b7b8ca1e1659 100644 --- a/Lib/tkinter/scrolledtext.py +++ b/Lib/tkinter/scrolledtext.py @@ -9,18 +9,25 @@ A Frame widget is inserted between the master and the text, to hold the Scrollbar widget. Most methods calls are inherited from the Text widget; Pack, Grid and Place methods are redirected to the Frame widget however. + +Pass use_ttk=True for the themed tkinter.ttk frame and scroll bar +instead of the classic tkinter widgets. """ -from tkinter import Frame, Text, Scrollbar, Pack, Grid, Place +from tkinter import Frame, Text, Scrollbar, Pack, Grid, Place, ttk from tkinter.constants import RIGHT, LEFT, Y, BOTH __all__ = ['ScrolledText'] class ScrolledText(Text): - def __init__(self, master=None, **kw): - self.frame = Frame(master) - self.vbar = Scrollbar(self.frame) + def __init__(self, master=None, *, use_ttk=False, **kw): + if use_ttk: + self.frame = ttk.Frame(master) + self.vbar = ttk.Scrollbar(self.frame) + else: + self.frame = Frame(master) + self.vbar = Scrollbar(self.frame) self.vbar.pack(side=RIGHT, fill=Y) kw['yscrollcommand'] = self.vbar.set diff --git a/Misc/NEWS.d/next/Library/2026-07-05-11-36-51.gh-issue-59396.Apl7sI.rst b/Misc/NEWS.d/next/Library/2026-07-05-11-36-51.gh-issue-59396.Apl7sI.rst new file mode 100644 index 000000000000..d4c0473ef372 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-07-05-11-36-51.gh-issue-59396.Apl7sI.rst @@ -0,0 +1,3 @@ +:class:`tkinter.scrolledtext.ScrolledText` gained a *use_ttk* parameter to use +the themed :mod:`tkinter.ttk` frame and scroll bar instead of the classic +:mod:`tkinter` widgets.