]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-59396: Add use_ttk parameter to tkinter ScrolledText (GH-153119)
authorSerhiy Storchaka <storchaka@gmail.com>
Fri, 10 Jul 2026 17:16:53 +0000 (20:16 +0300)
committerGitHub <noreply@github.com>
Fri, 10 Jul 2026 17:16:53 +0000 (17:16 +0000)
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 <noreply@anthropic.com>
Doc/library/tkinter.scrolledtext.rst
Doc/whatsnew/3.16.rst
Lib/test/test_tkinter/test_scrolledtext.py
Lib/tkinter/scrolledtext.py
Misc/NEWS.d/next/Library/2026-07-05-11-36-51.gh-issue-59396.Apl7sI.rst [new file with mode: 0644]

index 30aef8748edb72b8da9f3a1bfdd251f9825294be..2b147873cc23493968460f157083705dcb1bf4ab 100644 (file)
@@ -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
index 06c3dbb2f0f1adcb0826f24224c6aeb2f5d06381..7cf1ad7ae298343318d99b55bebaaf1d765f1415 100644 (file)
@@ -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`,
index 913e7d8aab6c46a8df660e7a652d63c88ac3923d..ea4789771bb091f03fbf62c76cc8411e6efda377 100644 (file)
@@ -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')
index 8dcead5e31930ea9c479c2b94e84551a1f2c6b84..b7b8ca1e1659717ee06576ddfe5fcbc675b2a894 100644 (file)
@@ -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 (file)
index 0000000..d4c0473
--- /dev/null
@@ -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.