From 810973c416a5a509c9fa05fc3567dc61f9341cf1 Mon Sep 17 00:00:00 2001 From: Mark Roseman Date: Tue, 10 Aug 2021 13:10:18 -0700 Subject: [PATCH 1/6] added some material to intro - context on tcl/tk versions, scope of tkinter and these docs --- Doc/library/tkinter.rst | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Doc/library/tkinter.rst b/Doc/library/tkinter.rst index beeffb8a548ee5..df12fb69438f29 100644 --- a/Doc/library/tkinter.rst +++ b/Doc/library/tkinter.rst @@ -20,6 +20,16 @@ demonstrating a simple Tk interface, letting you know that :mod:`tkinter` is properly installed on your system, and also showing what version of Tcl/Tk is installed, so you can read the Tcl/Tk documentation specific to that version. +Tkinter supports a range of Tcl/Tk versions, built either with or +without thread support. The official Python binary release bundles Tcl/Tk 8.6 +threaded. See the source code for the :mode:`_tkinter` module +for more information about supported versions. + +Tkinter is not a thin wrapper, but adds a fair amount of its own logic to +make the experience more pythonic. This documentation will concentrate on these +additions and changes, and refer to the official Tcl/Tk documentation for +details that are unchanged. + .. seealso:: Tkinter documentation: From 015c7ff37f560b57e9be8357fc771b84e0bbf7e3 Mon Sep 17 00:00:00 2001 From: Mark Roseman Date: Tue, 10 Aug 2021 13:13:50 -0700 Subject: [PATCH 2/6] new architecture section providing an overview of tcl, tk, ttk, and tix --- Doc/library/tkinter.rst | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/Doc/library/tkinter.rst b/Doc/library/tkinter.rst index df12fb69438f29..ee30faa39a4fff 100644 --- a/Doc/library/tkinter.rst +++ b/Doc/library/tkinter.rst @@ -72,6 +72,47 @@ details that are unchanged. Brent Welch's encyclopedic book. +Architecture +------------ + +Tcl/Tk is not a single library but rather consists of a few distinct +modules, each with a separate functionality and its own official +documentation. Python's binary releases also ship an add-on module +together with it. + +Tcl + Tcl is a dynamic interpreted programming language, just like Python. Though + it can be used on its own as a general-purpose programming language, it is + most commonly embedded into C applications as a scripting engine or an + interface to the Tk toolkit. The Tcl library has a C interface to + create and manage one or more instances of a Tcl interpreter, run Tcl + commands and scripts in those instances, and add custom commands + implemented in either Tcl or C. Each interpreter has an event queue, + and there are facilities to send events to it and process them. + Unlike Python, Tcl's execution model is designed around cooperative + multitasking, and Tkinter bridges this difference + (see `Threading model`_ for details). + +Tk + Tk is a `Tcl package `_ implemented in C + that adds custom commands to create and manipulate GUI widgets. Each + :class:`Tk` object embeds its own Tcl interpreter instance with Tk loaded into + it. Tk's widgets are very customizable, though at the cost of a dated appearance. + Tk uses Tcl's event queue to generate and process GUI events. + +Ttk + Themed Tk (Ttk) is a newer family of Tk widgets that provide a much better + appearance on different platforms than many of the classic Tk widgets. + Ttk is distributed as part of Tk, starting with Tk version 8.5. Python + bindings are provided in a separate module, :mod:`tkinter.ttk`. + +Tix + `Tix`_ is an older + third-party Tcl package, an add-on for Tk that adds several new widgets. + Python bindings are found in the :mod:`tkinter.tix` module. + It's deprecated in favor of Ttk. + + Tkinter Modules --------------- From 292471f05e6071c0618d9a9aa4e4d0fdf8c6fe05 Mon Sep 17 00:00:00 2001 From: Mark Roseman Date: Tue, 10 Aug 2021 13:16:07 -0700 Subject: [PATCH 3/6] new section on threading model --- Doc/library/tkinter.rst | 53 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/Doc/library/tkinter.rst b/Doc/library/tkinter.rst index ee30faa39a4fff..41e20dd177f52a 100644 --- a/Doc/library/tkinter.rst +++ b/Doc/library/tkinter.rst @@ -428,6 +428,59 @@ Xlib (C) the Xlib library to draw graphics on the screen. +Threading model +--------------- + +Python and Tcl/Tk have very different threading models, which :mod:`tkinter` +tries to bridge. If you use threads, you may need to be aware of this. + +A Python interpreter may have many threads associated with it. In Tcl, multiple +threads can be created, but each thread has a separate Tcl interpreter instance +associated with it. Threads can also create more than one interpreter instance, +though each interpreter instance can be used only by the one thread that created it. + +Each :class:`Tk` object created by :mod:`tkinter` contains a Tcl interpreter. +It also keeps track of which thread created that interpreter. Calls to +:mod:`tkinter` can be made from any Python thread. Internally, if a call comes +from a thread other than the one that created the :class:`Tk` object, an event +is posted to the interpreter's event queue, and when executed, the result is +returned to the calling Python thread. + +Tcl/Tk applications are normally event-driven, meaning that after initialization, +the interpreter runs an event loop (i.e. :func:`Tk.mainloop`) and responds to events. +Because it is single-threaded, event handlers must respond quickly, otherwise they +will block other events from being processed. To avoid this, any long-running +computations should not run in an event handler, but are either broken into smaller +pieces using timers, or run in another thread. This is different from many GUI +toolkits where the GUI runs in a completely separate thread from all application +code including event handlers. + +If the Tcl interpreter is not running the event loop and processing events, any +:mod:`tkinter` calls made from threads other than the one running the Tcl +interpreter will fail. + +A number of special cases exist: + + * Tcl/Tk libraries can be built so they are not thread-aware. In this case, + :mod:`tkinter` calls the library from the originating Python thread, even + if this is different than the thread that created the Tcl interpreter. A global + lock ensures only one call occurs at a time. + + * While :mod:`tkinter` allows you to create more than one instance of a :class:`Tk` + object (with it's own interpreter), all interpreters that are part of the same + thread share a common event queue, which gets ugly fast. In practice, don't create + more than one instance of :class:`Tk` at a time. Otherwise, it's best to create + them in separate threads and ensure you're running a thread-aware Tcl/Tk build. + + * Blocking event handlers are not the only way to prevent the Tcl interpreter from + reentering the event loop. It is even possible to run multiple nested event loops + or abandon the event loop entirely. If you're doing anything tricky when it comes + to events or threads, be aware of these possibilities. + + * There are a few select :mod:`tkinter` functions that presently work only when + called from the thread that created the Tcl interpreter. + + Handy Reference --------------- From 1d8d23387933ac7e0b4e72bd9af5749a23fee129 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Langa?= Date: Wed, 11 Aug 2021 17:03:43 +0200 Subject: [PATCH 4/6] typo: s/mode/mod/ --- Doc/library/tkinter.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/tkinter.rst b/Doc/library/tkinter.rst index 41e20dd177f52a..96b923fea69b7a 100644 --- a/Doc/library/tkinter.rst +++ b/Doc/library/tkinter.rst @@ -22,7 +22,7 @@ installed, so you can read the Tcl/Tk documentation specific to that version. Tkinter supports a range of Tcl/Tk versions, built either with or without thread support. The official Python binary release bundles Tcl/Tk 8.6 -threaded. See the source code for the :mode:`_tkinter` module +threaded. See the source code for the :mod:`_tkinter` module for more information about supported versions. Tkinter is not a thin wrapper, but adds a fair amount of its own logic to From 90e769919ff64b0cf99bf5598eaa29b29582f231 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Langa?= Date: Wed, 11 Aug 2021 18:06:35 +0200 Subject: [PATCH 5/6] Add Blurb --- .../next/Documentation/2021-08-11-18-02-06.bpo-33479.rCe4c5.rst | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 Misc/NEWS.d/next/Documentation/2021-08-11-18-02-06.bpo-33479.rCe4c5.rst diff --git a/Misc/NEWS.d/next/Documentation/2021-08-11-18-02-06.bpo-33479.rCe4c5.rst b/Misc/NEWS.d/next/Documentation/2021-08-11-18-02-06.bpo-33479.rCe4c5.rst new file mode 100644 index 00000000000000..c4a8a981939dec --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2021-08-11-18-02-06.bpo-33479.rCe4c5.rst @@ -0,0 +1,2 @@ +Tkinter documentation has been greatly expanded with new "Architecture" and +"Threading model" sections. From 7e4c859d63afaa1de2ede251da5a03bbe5dc353a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Langa?= Date: Wed, 11 Aug 2021 18:10:12 +0200 Subject: [PATCH 6/6] More minor fixes --- Doc/library/tkinter.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Doc/library/tkinter.rst b/Doc/library/tkinter.rst index 96b923fea69b7a..39766486f64f91 100644 --- a/Doc/library/tkinter.rst +++ b/Doc/library/tkinter.rst @@ -107,7 +107,7 @@ Ttk bindings are provided in a separate module, :mod:`tkinter.ttk`. Tix - `Tix`_ is an older + `Tix `_ is an older third-party Tcl package, an add-on for Tk that adds several new widgets. Python bindings are found in the :mod:`tkinter.tix` module. It's deprecated in favor of Ttk. @@ -467,7 +467,7 @@ A number of special cases exist: lock ensures only one call occurs at a time. * While :mod:`tkinter` allows you to create more than one instance of a :class:`Tk` - object (with it's own interpreter), all interpreters that are part of the same + object (with its own interpreter), all interpreters that are part of the same thread share a common event queue, which gets ugly fast. In practice, don't create more than one instance of :class:`Tk` at a time. Otherwise, it's best to create them in separate threads and ensure you're running a thread-aware Tcl/Tk build.