bpo-33479: Add architecture and threading model sections to Tkinter m… · python/cpython@2666d70

@@ -20,6 +20,16 @@ demonstrating a simple Tk interface, letting you know that :mod:`tkinter` is

2020

properly installed on your system, and also showing what version of Tcl/Tk is

2121

installed, so you can read the Tcl/Tk documentation specific to that version.

222223+

Tkinter supports a range of Tcl/Tk versions, built either with or

24+

without thread support. The official Python binary release bundles Tcl/Tk 8.6

25+

threaded. See the source code for the :mod:`_tkinter` module

26+

for more information about supported versions.

27+28+

Tkinter is not a thin wrapper, but adds a fair amount of its own logic to

29+

make the experience more pythonic. This documentation will concentrate on these

30+

additions and changes, and refer to the official Tcl/Tk documentation for

31+

details that are unchanged.

32+2333

.. seealso::

24342535

Tkinter documentation:

@@ -65,6 +75,47 @@ installed, so you can read the Tcl/Tk documentation specific to that version.

6575

Brent Welch's encyclopedic book.

6676677778+

Architecture

79+

------------

80+81+

Tcl/Tk is not a single library but rather consists of a few distinct

82+

modules, each with a separate functionality and its own official

83+

documentation. Python's binary releases also ship an add-on module

84+

together with it.

85+86+

Tcl

87+

Tcl is a dynamic interpreted programming language, just like Python. Though

88+

it can be used on its own as a general-purpose programming language, it is

89+

most commonly embedded into C applications as a scripting engine or an

90+

interface to the Tk toolkit. The Tcl library has a C interface to

91+

create and manage one or more instances of a Tcl interpreter, run Tcl

92+

commands and scripts in those instances, and add custom commands

93+

implemented in either Tcl or C. Each interpreter has an event queue,

94+

and there are facilities to send events to it and process them.

95+

Unlike Python, Tcl's execution model is designed around cooperative

96+

multitasking, and Tkinter bridges this difference

97+

(see `Threading model`_ for details).

98+99+

Tk

100+

Tk is a `Tcl package <http://wiki.tcl.tk/37432>`_ implemented in C

101+

that adds custom commands to create and manipulate GUI widgets. Each

102+

:class:`Tk` object embeds its own Tcl interpreter instance with Tk loaded into

103+

it. Tk's widgets are very customizable, though at the cost of a dated appearance.

104+

Tk uses Tcl's event queue to generate and process GUI events.

105+106+

Ttk

107+

Themed Tk (Ttk) is a newer family of Tk widgets that provide a much better

108+

appearance on different platforms than many of the classic Tk widgets.

109+

Ttk is distributed as part of Tk, starting with Tk version 8.5. Python

110+

bindings are provided in a separate module, :mod:`tkinter.ttk`.

111+112+

Tix

113+

`Tix <https://core.tcl.tk/jenglish/gutter/packages/tix.html>`_ is an older

114+

third-party Tcl package, an add-on for Tk that adds several new widgets.

115+

Python bindings are found in the :mod:`tkinter.tix` module.

116+

It's deprecated in favor of Ttk.

117+118+68119

Tkinter Modules

69120

---------------

70121

@@ -380,6 +431,59 @@ Xlib (C)

380431

the Xlib library to draw graphics on the screen.

381432382433434+

Threading model

435+

---------------

436+437+

Python and Tcl/Tk have very different threading models, which :mod:`tkinter`

438+

tries to bridge. If you use threads, you may need to be aware of this.

439+440+

A Python interpreter may have many threads associated with it. In Tcl, multiple

441+

threads can be created, but each thread has a separate Tcl interpreter instance

442+

associated with it. Threads can also create more than one interpreter instance,

443+

though each interpreter instance can be used only by the one thread that created it.

444+445+

Each :class:`Tk` object created by :mod:`tkinter` contains a Tcl interpreter.

446+

It also keeps track of which thread created that interpreter. Calls to

447+

:mod:`tkinter` can be made from any Python thread. Internally, if a call comes

448+

from a thread other than the one that created the :class:`Tk` object, an event

449+

is posted to the interpreter's event queue, and when executed, the result is

450+

returned to the calling Python thread.

451+452+

Tcl/Tk applications are normally event-driven, meaning that after initialization,

453+

the interpreter runs an event loop (i.e. :func:`Tk.mainloop`) and responds to events.

454+

Because it is single-threaded, event handlers must respond quickly, otherwise they

455+

will block other events from being processed. To avoid this, any long-running

456+

computations should not run in an event handler, but are either broken into smaller

457+

pieces using timers, or run in another thread. This is different from many GUI

458+

toolkits where the GUI runs in a completely separate thread from all application

459+

code including event handlers.

460+461+

If the Tcl interpreter is not running the event loop and processing events, any

462+

:mod:`tkinter` calls made from threads other than the one running the Tcl

463+

interpreter will fail.

464+465+

A number of special cases exist:

466+467+

* Tcl/Tk libraries can be built so they are not thread-aware. In this case,

468+

:mod:`tkinter` calls the library from the originating Python thread, even

469+

if this is different than the thread that created the Tcl interpreter. A global

470+

lock ensures only one call occurs at a time.

471+472+

* While :mod:`tkinter` allows you to create more than one instance of a :class:`Tk`

473+

object (with its own interpreter), all interpreters that are part of the same

474+

thread share a common event queue, which gets ugly fast. In practice, don't create

475+

more than one instance of :class:`Tk` at a time. Otherwise, it's best to create

476+

them in separate threads and ensure you're running a thread-aware Tcl/Tk build.

477+478+

* Blocking event handlers are not the only way to prevent the Tcl interpreter from

479+

reentering the event loop. It is even possible to run multiple nested event loops

480+

or abandon the event loop entirely. If you're doing anything tricky when it comes

481+

to events or threads, be aware of these possibilities.

482+483+

* There are a few select :mod:`tkinter` functions that presently work only when

484+

called from the thread that created the Tcl interpreter.

485+486+383487

Handy Reference

384488

---------------

385489