mirror of
https://github.com/python/cpython.git
synced 2026-07-28 12:48:27 -04:00
[3.15] gh-153550: Modernize the older prose sections of the tkinter documentation (GH-153647) (GH-153773)
Refresh the narrative "Tkinter life preserver" and "Handy reference"
sections to match the overhauled reference (gh-86726 and gh-153549).
* Rework "The packer" into a general "Geometry management" section
covering grid, pack and place, and cross-link it with the Grid, Pack
and Place reference classes.
* Rework "The window manager" and "Coupling widget variables", replacing
the dated App(Frame) examples with direct Tk() and ttk examples.
* Replace page-number citations to Ousterhout's book with links to the
relevant Tk man pages.
* Modernize the tkinter.ttk front matter and its Tcl/Tk links, and add
cross-references between the two documents.
* Reconcile the "Packer options" and "Tk option data types" lists with
the reference, and fill in the empty Entry index list.
* Fix the malformed target-selection list in tkinter.dnd.
(cherry picked from commit 93beea7e5a)
Co-authored-by: Serhiy Storchaka <[email protected]>
Co-authored-by: Claude Opus 4.8 (1M context) <[email protected]>
This commit is contained in:
co-authored by
Serhiy Storchaka
Claude Opus 4.8
parent
25eb043eba
commit
04baaae20c
@@ -16,21 +16,22 @@ a single application, within the same window or between windows. To enable an
|
||||
object to be dragged, you must create an event binding for it that starts the
|
||||
drag-and-drop process. Typically, you bind a ButtonPress event to a callback
|
||||
function that you write (see :ref:`Bindings-and-Events`). The function should
|
||||
call :func:`dnd_start`, where 'source' is the object to be dragged, and 'event'
|
||||
call :func:`dnd_start`, where *source* is the object to be dragged, and *event*
|
||||
is the event that invoked the call (the argument to your callback function).
|
||||
|
||||
Selection of a target object occurs as follows:
|
||||
|
||||
#. Top-down search of area under mouse for target widget
|
||||
#. Top-down search of the area under the mouse for a target widget:
|
||||
|
||||
* Target widget should have a callable *dnd_accept* attribute
|
||||
* If *dnd_accept* is not present or returns ``None``, search moves to parent widget
|
||||
* If no target widget is found, then the target object is ``None``
|
||||
* the target widget should have a callable *dnd_accept* attribute;
|
||||
* if *dnd_accept* is not present or returns ``None``,
|
||||
the search moves to the parent widget;
|
||||
* if no target widget is found, the target object is ``None``.
|
||||
|
||||
2. Call to *<old_target>.dnd_leave(source, event)*
|
||||
#. Call to *<new_target>.dnd_enter(source, event)*
|
||||
#. Call to *<target>.dnd_commit(source, event)* to notify of drop
|
||||
#. Call to *<source>.dnd_end(target, event)* to signal end of drag-and-drop
|
||||
#. Call to ``<old_target>.dnd_leave(source, event)``.
|
||||
#. Call to ``<new_target>.dnd_enter(source, event)``.
|
||||
#. Call to ``<target>.dnd_commit(source, event)`` to notify of the drop.
|
||||
#. Call to ``<source>.dnd_end(target, event)`` to signal the end of drag-and-drop.
|
||||
|
||||
|
||||
.. class:: DndHandler(source, event)
|
||||
|
||||
+183
-129
@@ -35,7 +35,8 @@ details that are unchanged.
|
||||
.. note::
|
||||
|
||||
Tcl/Tk 8.5 (2007) introduced a modern set of themed user interface components
|
||||
along with a new API to use them. Both old and new APIs are still available.
|
||||
along with a new API to use them (see :mod:`tkinter.ttk`).
|
||||
Both old and new APIs are still available.
|
||||
Most documentation you will find online still uses the old API and
|
||||
can be woefully outdated.
|
||||
|
||||
@@ -519,6 +520,17 @@ Use the config() method to update multiple attrs subsequent to object creation
|
||||
|
||||
fred.config(fg="red", bg="blue")
|
||||
|
||||
.. note::
|
||||
|
||||
The ``fg`` and ``bg`` options used here,
|
||||
and other options that control a widget's appearance,
|
||||
belong to the classic :mod:`!tkinter` widgets.
|
||||
The themed :mod:`tkinter.ttk` widgets recommended in the introduction
|
||||
do not accept them;
|
||||
style a themed widget through the :class:`ttk.Style <tkinter.ttk.Style>`
|
||||
class instead.
|
||||
The three ways of setting an option shown above apply to both widget sets.
|
||||
|
||||
For a complete explanation of a given option and its behavior, see the Tk man
|
||||
pages for the widget in question.
|
||||
|
||||
@@ -567,65 +579,84 @@ their values. This is meant only as an example.
|
||||
|
||||
|
||||
.. _pack-the-packer:
|
||||
.. _tkinter-geometry-management:
|
||||
.. _the-packer:
|
||||
.. _packer-options:
|
||||
|
||||
The packer
|
||||
^^^^^^^^^^
|
||||
Geometry management
|
||||
^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. index:: single: packing (widgets)
|
||||
.. index::
|
||||
single: geometry management (widgets)
|
||||
single: packing (widgets)
|
||||
|
||||
The packer is one of Tk's geometry-management mechanisms. Geometry managers
|
||||
are used to specify the relative positioning of widgets within their container.
|
||||
In contrast to the more cumbersome *placer* (which is
|
||||
used less commonly, and we do not cover here), the packer takes qualitative
|
||||
relationship specification - *above*, *to the left of*, *filling*, etc - and
|
||||
works everything out to determine the exact placement coordinates for you.
|
||||
Creating a widget does not display it.
|
||||
A widget appears only after it has been handed to a *geometry manager*,
|
||||
which works out its size and position inside its container
|
||||
and keeps the layout up to date as the container is resized or its content changes.
|
||||
Forgetting to call a geometry manager is a common early mistake:
|
||||
the widget is created, but nothing shows up.
|
||||
|
||||
The size of any container widget is determined by the size of the "content widgets"
|
||||
inside. The packer is used to control where content widgets appear inside the
|
||||
container into which they are packed. You can pack widgets into frames, and frames
|
||||
into other frames, in order to achieve the kind of layout you desire.
|
||||
Additionally, the arrangement is dynamically adjusted to accommodate incremental
|
||||
changes to the configuration, once it is packed.
|
||||
Tk provides three geometry managers.
|
||||
Each is inherited by every widget, so any widget can be managed by any of them
|
||||
(but see the warning below about the incompatibility of grid and pack).
|
||||
The choice depends on the kind of layout you want.
|
||||
|
||||
Note that widgets do not appear until they have had their geometry specified
|
||||
with a geometry manager.
|
||||
It's a common early mistake to leave out the geometry specification, and then
|
||||
be surprised when the widget is created but nothing appears.
|
||||
A widget will appear only after it has had, for example, the packer's
|
||||
:meth:`~Pack.pack` method applied to it.
|
||||
:meth:`grid <Grid.grid_configure>`
|
||||
Arranges widgets in a two-dimensional table of rows and columns.
|
||||
It is the most flexible manager and the one to reach for by default:
|
||||
layouts that would otherwise need several nested frames can often be
|
||||
expressed as a single grid,
|
||||
and rows and columns can be told how to absorb extra space.
|
||||
|
||||
The pack() method can be called with keyword-option/value pairs that control
|
||||
where the widget is to appear within its container, and how it is to behave when
|
||||
the main application window is resized. Here are some examples::
|
||||
::
|
||||
|
||||
fred.pack() # defaults to side = "top"
|
||||
fred.pack(side="left")
|
||||
fred.pack(expand=1)
|
||||
ttk.Label(frm, text="Name:").grid(column=0, row=0, sticky="w")
|
||||
ttk.Entry(frm).grid(column=1, row=0)
|
||||
ttk.Button(frm, text="OK").grid(column=1, row=1, sticky="e")
|
||||
|
||||
:meth:`pack <Pack.pack_configure>`
|
||||
Stacks widgets against one side of their container
|
||||
-- ``"top"`` (the default), ``"bottom"``, ``"left"`` or ``"right"`` --
|
||||
and can make them fill or expand into the space that is left.
|
||||
It is convenient for simple arrangements,
|
||||
such as a single row or column of widgets
|
||||
or a content area framed by a toolbar and a status bar.
|
||||
|
||||
Packer options
|
||||
^^^^^^^^^^^^^^
|
||||
::
|
||||
|
||||
For more extensive information on the packer and the options that it can take,
|
||||
see the man pages and page 183 of John Ousterhout's book.
|
||||
toolbar.pack(side="top", fill="x")
|
||||
status.pack(side="bottom", fill="x")
|
||||
body.pack(side="left", expand=True, fill="both")
|
||||
|
||||
anchor
|
||||
Anchor type. Denotes where the packer is to place each content in its parcel.
|
||||
:meth:`place <Place.place_configure>`
|
||||
Positions each widget at an explicit spot,
|
||||
given either as absolute screen distances or as a fraction of the container's size.
|
||||
It offers the most control but the least automatic behavior, and is used the least;
|
||||
it suits special cases such as overlapping widgets or precise custom layouts.
|
||||
|
||||
expand
|
||||
boolean, ``0`` or ``1``.
|
||||
::
|
||||
|
||||
fill
|
||||
Legal values: ``'x'``, ``'y'``, ``'both'``, ``'none'``.
|
||||
background.place(x=0, y=0, relwidth=1.0, relheight=1.0)
|
||||
badge.place(relx=1.0, rely=0.0, anchor="ne")
|
||||
|
||||
ipadx and ipady
|
||||
A distance - designating internal padding on each side of the content.
|
||||
Layouts are built up by nesting:
|
||||
grid or pack widgets, including frames, inside a frame or toplevel.
|
||||
Toplevels are managed by the OS window manager.
|
||||
Classic and themed :mod:`tkinter.ttk` widgets can be managed interchangeably.
|
||||
|
||||
padx and pady
|
||||
A distance - designating external padding on each side of the content.
|
||||
.. warning::
|
||||
|
||||
side
|
||||
Legal values are: ``'left'``, ``'right'``, ``'top'``, ``'bottom'``.
|
||||
Do not apply :meth:`!pack` and :meth:`!grid` to two widgets that share the same container.
|
||||
The two managers negotiate sizes in incompatible ways,
|
||||
and the application can hang as they repeatedly resize the container against each other.
|
||||
To combine them, keep each manager's widgets in a separate frame.
|
||||
|
||||
The full set of options accepted by each manager, with their values and defaults,
|
||||
is documented under :meth:`Grid.grid_configure`, :meth:`Pack.pack_configure`
|
||||
and :meth:`Place.place_configure`;
|
||||
see also the :manpage:`grid(3tk)`, :manpage:`pack(3tk)` and :manpage:`place(3tk)`
|
||||
man pages.
|
||||
|
||||
|
||||
.. _coupling-widget-variables:
|
||||
@@ -633,105 +664,98 @@ side
|
||||
Coupling widget variables
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The current-value setting of some widgets (like text entry widgets) can be
|
||||
connected directly to application variables by using special options. These
|
||||
options are ``variable``, ``textvariable``, ``onvalue``, ``offvalue``, and
|
||||
``value``. This connection works both ways: if the variable changes for any
|
||||
reason, the widget it's connected to will be updated to reflect the new value.
|
||||
Some widgets can tie their current value directly to a program variable,
|
||||
so that the two stay in sync.
|
||||
Options such as ``variable``, ``textvariable``, ``value``, ``onvalue`` and
|
||||
``offvalue`` set up this connection:
|
||||
when the user changes the widget the variable is updated,
|
||||
and when the variable is set the widget redraws to match.
|
||||
|
||||
Unfortunately, in the current implementation of :mod:`!tkinter` it is not
|
||||
possible to hand over an arbitrary Python variable to a widget through a
|
||||
``variable`` or ``textvariable`` option. The only kinds of variables for which
|
||||
this works are variables that are subclassed from a class called Variable,
|
||||
defined in :mod:`!tkinter`.
|
||||
A widget can be linked only to a :class:`Variable` object,
|
||||
not to an ordinary Python variable.
|
||||
This is not a limitation of :mod:`!tkinter`
|
||||
but a consequence of how the two languages differ:
|
||||
the link relies on Tcl being notified every time the value changes,
|
||||
and Python offers no way to react when a plain variable is reassigned.
|
||||
A :class:`Variable` sidesteps this by keeping its value inside the Tcl interpreter
|
||||
and exposing it through explicit :meth:`~Variable.get` and :meth:`~Variable.set` methods.
|
||||
|
||||
There are many useful subclasses of Variable already defined:
|
||||
:class:`StringVar`, :class:`IntVar`, :class:`DoubleVar`, and
|
||||
:class:`BooleanVar`.
|
||||
To read the current value of such a variable, call the :meth:`~Variable.get`
|
||||
method on it, and to change its value you call the :meth:`!set` method.
|
||||
If you follow this protocol, the widget will always track the value of the
|
||||
variable, with no further intervention on your part.
|
||||
Ready-made subclasses cover the common types:
|
||||
:class:`StringVar`, :class:`IntVar`, :class:`DoubleVar` and :class:`BooleanVar`.
|
||||
Pass one as a widget's ``textvariable`` (or ``variable``) option,
|
||||
then read and update it with :meth:`~Variable.get` and :meth:`~Variable.set`;
|
||||
the widget tracks it with no further work on your part.
|
||||
|
||||
Keep a reference to the variable for as long as a widget uses it, for example
|
||||
by storing it as an attribute (see :class:`Variable`).
|
||||
Keep a reference to the variable for as long as the widget uses it
|
||||
-- for example by storing it as an attribute.
|
||||
A :class:`Variable` that is garbage collected removes its underlying Tcl variable,
|
||||
breaking the connection to the widget (see :class:`Variable`).
|
||||
|
||||
For example::
|
||||
|
||||
import tkinter as tk
|
||||
|
||||
class App(tk.Frame):
|
||||
def __init__(self, master):
|
||||
super().__init__(master)
|
||||
self.pack()
|
||||
|
||||
self.entrythingy = tk.Entry()
|
||||
self.entrythingy.pack()
|
||||
|
||||
# Create the application variable.
|
||||
self.contents = tk.StringVar()
|
||||
# Set it to some value.
|
||||
self.contents.set("this is a variable")
|
||||
# Tell the entry widget to watch this variable.
|
||||
self.entrythingy["textvariable"] = self.contents
|
||||
|
||||
# Define a callback for when the user hits return.
|
||||
# It prints the current value of the variable.
|
||||
self.entrythingy.bind('<Key-Return>',
|
||||
self.print_contents)
|
||||
|
||||
def print_contents(self, event):
|
||||
print("Hi. The current entry content is:",
|
||||
self.contents.get())
|
||||
from tkinter import ttk
|
||||
|
||||
root = tk.Tk()
|
||||
myapp = App(root)
|
||||
myapp.mainloop()
|
||||
|
||||
# Create the application variable and give it an initial value.
|
||||
contents = tk.StringVar(value="this is a variable")
|
||||
|
||||
# Tell the entry widget to track the variable.
|
||||
entry = ttk.Entry(root, textvariable=contents)
|
||||
entry.pack()
|
||||
|
||||
# Print the current value whenever the user presses Return.
|
||||
def print_contents(event):
|
||||
print("The current entry content is:", contents.get())
|
||||
|
||||
entry.bind("<Return>", print_contents)
|
||||
|
||||
# Setting the variable from the program updates the entry through the
|
||||
# same link.
|
||||
def clear():
|
||||
contents.set("")
|
||||
|
||||
ttk.Button(root, text="Clear", command=clear).pack()
|
||||
|
||||
root.mainloop()
|
||||
|
||||
.. _tkinter-window-manager:
|
||||
|
||||
The window manager
|
||||
^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. index:: single: window manager (widgets)
|
||||
|
||||
In Tk, there is a utility command, ``wm``, for interacting with the window
|
||||
manager. Options to the ``wm`` command allow you to control things like titles,
|
||||
placement, icon bitmaps, and the like. In :mod:`!tkinter`, these commands have
|
||||
been implemented as methods on the :class:`Wm` class. Toplevel widgets are
|
||||
subclassed from the :class:`Wm` class, and so can call the :class:`Wm` methods
|
||||
directly.
|
||||
The *window manager* is the part of the desktop responsible for the title bar,
|
||||
border and controls drawn around each top-level window,
|
||||
and for such things as its title, position, size and icon.
|
||||
Tk gives access to these through the :class:`Wm` mixin,
|
||||
which is inherited by the :class:`Tk` root window and by every :class:`Toplevel`.
|
||||
You therefore call the window-manager methods directly on a top-level window.
|
||||
Each has a short name and an equivalent ``wm_``-prefixed name,
|
||||
for example :meth:`~Wm.title` and :meth:`~Wm.wm_title`.
|
||||
|
||||
To get at the toplevel window that contains a given widget, you can often just
|
||||
refer to the widget's :attr:`~Tk.master`.
|
||||
Of course if the widget has been packed inside of a frame, the :attr:`!master`
|
||||
won't represent a toplevel window.
|
||||
To get at the toplevel window that contains an arbitrary widget, you can call
|
||||
the :meth:`~Misc.winfo_toplevel` method.
|
||||
There is also a :meth:`!_root` method; it begins with an underscore to denote
|
||||
the fact that this function is part of the implementation, and not an interface
|
||||
to Tk functionality.
|
||||
It returns the application's root window rather than the nearest enclosing
|
||||
toplevel.
|
||||
These methods act on the top-level window
|
||||
whether its content is built from the classic widgets or the themed :mod:`tkinter.ttk` widgets.
|
||||
To reach the top-level window containing an arbitrary widget,
|
||||
call its :meth:`~Misc.winfo_toplevel` method.
|
||||
|
||||
Here are some examples of typical usage::
|
||||
For example::
|
||||
|
||||
import tkinter as tk
|
||||
from tkinter import ttk
|
||||
|
||||
class App(tk.Frame):
|
||||
def __init__(self, master=None):
|
||||
super().__init__(master)
|
||||
self.pack()
|
||||
root = tk.Tk()
|
||||
root.title("My Application")
|
||||
root.geometry("640x480")
|
||||
root.minsize(320, 240)
|
||||
|
||||
# create the application
|
||||
myapp = App()
|
||||
ttk.Label(root, text="Hello").pack(padx=20, pady=20)
|
||||
|
||||
#
|
||||
# here are method calls to the window manager class
|
||||
#
|
||||
myapp.master.title("My Do-Nothing Application")
|
||||
myapp.master.maxsize(1000, 400)
|
||||
root.mainloop()
|
||||
|
||||
# start the program
|
||||
myapp.mainloop()
|
||||
See :class:`Wm` for the full set of window-manager methods.
|
||||
|
||||
|
||||
.. _Tk-option-data-types:
|
||||
@@ -741,6 +765,9 @@ Tk option data types
|
||||
|
||||
.. index:: single: Tk Option Data Types
|
||||
|
||||
Many widget options documented in the reference
|
||||
accept values of a small number of common types, described here.
|
||||
|
||||
anchor
|
||||
Legal values are points of the compass: ``"n"``, ``"ne"``, ``"e"``, ``"se"``,
|
||||
``"s"``, ``"sw"``, ``"w"``, ``"nw"``, and also ``"center"``.
|
||||
@@ -766,7 +793,8 @@ color
|
||||
Colors can be given as the names of X colors in the rgb.txt file, or as strings
|
||||
representing RGB values in 4 bit: ``"#RGB"``, 8 bit: ``"#RRGGBB"``, 12 bit:
|
||||
``"#RRRGGGBBB"``, or 16 bit: ``"#RRRRGGGGBBBB"`` ranges, where R,G,B here
|
||||
represent any legal hex digit. See page 160 of Ousterhout's book for details.
|
||||
represent any legal hex digit. See the :manpage:`colors(3tk)` man page for
|
||||
the list of named colors.
|
||||
|
||||
cursor
|
||||
The name of the mouse cursor to display while the pointer is over the widget.
|
||||
@@ -841,8 +869,7 @@ sequence
|
||||
``<modifier-modifier-type-detail>`` form (for example ``"<Enter>"`` or
|
||||
``"<Control-Button-1>"``); application-defined virtual events use double angle
|
||||
brackets, as in ``"<<Paste>>"``. (See the
|
||||
:manpage:`bind(3tk)` man page, and page 201 of John Ousterhout's book,
|
||||
:title-reference:`Tcl and the Tk Toolkit (2nd edition)`, for details).
|
||||
:manpage:`bind(3tk)` man page for details.)
|
||||
|
||||
func
|
||||
is a Python function, taking one argument, to be invoked when the event occurs.
|
||||
@@ -914,9 +941,32 @@ point at a specific place in a Text widget, or to particular characters in an
|
||||
Entry widget, or to particular menu items in a Menu widget.
|
||||
|
||||
Entry widget indexes (index, view index, etc.)
|
||||
Entry widgets have options that refer to character positions in the text being
|
||||
displayed. You can use these :mod:`!tkinter` functions to access these special
|
||||
points in text widgets:
|
||||
Entry widgets have methods and options that refer to character positions
|
||||
in the text being displayed.
|
||||
Anytime an index is needed, you may pass in:
|
||||
|
||||
* an integer which refers to the numeric position of a character,
|
||||
counted from the beginning of the text, starting with 0;
|
||||
|
||||
* the string ``"anchor"``,
|
||||
which refers to the anchor point of the selection,
|
||||
set with the widget's selection methods;
|
||||
|
||||
* the string ``"end"``,
|
||||
which refers to the position just after the last character;
|
||||
|
||||
* the string ``"insert"``,
|
||||
which refers to the character just after the insertion cursor;
|
||||
|
||||
* the strings ``"sel.first"`` and ``"sel.last"``,
|
||||
which refer to the first character in the selection
|
||||
and the position just after the last
|
||||
(it is an error to use these if there is no selection);
|
||||
|
||||
* a string consisting of ``@`` followed by an integer, as in ``"@6"``,
|
||||
where the integer is interpreted as an x pixel coordinate
|
||||
in the entry's coordinate system,
|
||||
selecting the character spanning that point.
|
||||
|
||||
Text widget indexes
|
||||
The index notation for Text widgets is very rich and is best described in the Tk
|
||||
@@ -934,8 +984,9 @@ Menu indexes (menu.invoke(), menu.entryconfig(), etc.)
|
||||
|
||||
* the string ``"last"`` which refers to the last menu item;
|
||||
|
||||
* An integer preceded by ``@``, as in ``@6``, where the integer is interpreted
|
||||
as a y pixel coordinate in the menu's coordinate system;
|
||||
* a string consisting of ``@`` followed by an integer, as in ``"@6"``, where
|
||||
the integer is interpreted as a y pixel coordinate in the menu's coordinate
|
||||
system;
|
||||
|
||||
* the string ``"none"``, which indicates no menu entry at all, most often used
|
||||
with menu.activate() to deactivate all entries, and finally,
|
||||
@@ -2270,6 +2321,7 @@ Base and mixin classes
|
||||
available on every top-level window.
|
||||
Each method has two equivalent spellings: a short name and a
|
||||
``wm_``-prefixed name (for example, :meth:`title` and :meth:`wm_title`).
|
||||
See also :ref:`tkinter-window-manager`.
|
||||
|
||||
.. method:: wm_aspect(minNumer=None, minDenom=None, maxNumer=None, maxDenom=None)
|
||||
:no-typesetting:
|
||||
@@ -2803,7 +2855,7 @@ Base and mixin classes
|
||||
The :class:`!Pack` mix-in is inherited by all widgets (through
|
||||
:class:`Widget`) and provides the methods for managing a widget with the
|
||||
*pack* geometry manager.
|
||||
See also :ref:`pack-the-packer`.
|
||||
See also :ref:`tkinter-geometry-management`.
|
||||
|
||||
.. note::
|
||||
|
||||
@@ -2935,6 +2987,7 @@ Base and mixin classes
|
||||
their container.
|
||||
The :class:`!Place` mix-in is inherited by all widgets (through
|
||||
:class:`Widget`).
|
||||
See also :ref:`tkinter-geometry-management`.
|
||||
|
||||
.. method:: configure(cnf={}, **kw)
|
||||
:no-typesetting:
|
||||
@@ -3027,6 +3080,7 @@ Base and mixin classes
|
||||
columns within their container.
|
||||
The :class:`!Grid` mix-in is inherited by all widgets (through
|
||||
:class:`Widget`).
|
||||
See also :ref:`tkinter-geometry-management`.
|
||||
|
||||
.. method:: configure(cnf={}, **kw)
|
||||
:no-typesetting:
|
||||
|
||||
+29
-16
@@ -11,21 +11,28 @@
|
||||
--------------
|
||||
|
||||
The :mod:`!tkinter.ttk` module provides access to the Tk themed widget set,
|
||||
introduced in Tk 8.5. It provides additional benefits including anti-aliased font
|
||||
rendering under X11 and window transparency (requiring a composition
|
||||
window manager on X11).
|
||||
introduced in Tk 8.5.
|
||||
Its widgets adapt their appearance to the platform's native theme,
|
||||
giving an application a better and more consistent look and feel
|
||||
than the classic :mod:`tkinter` widgets, whose appearance is fixed.
|
||||
|
||||
The basic idea for :mod:`!tkinter.ttk` is to separate, to the extent possible,
|
||||
the code implementing a widget's behavior from the code implementing its
|
||||
appearance.
|
||||
|
||||
Ttk widgets are used just like the classic :mod:`tkinter` widgets
|
||||
and share the same machinery:
|
||||
the widget hierarchy, the geometry managers, variable coupling and event binding.
|
||||
Those foundational concepts are covered in the :mod:`tkinter` documentation
|
||||
and are not repeated here.
|
||||
|
||||
.. versionadded:: 3.1
|
||||
|
||||
|
||||
.. seealso::
|
||||
|
||||
`Tk Widget Styling Support <https://core.tcl.tk/tips/doc/trunk/tip/48.md>`_
|
||||
A document introducing theming support for Tk
|
||||
`Tk Widget Styling Support (TIP #48) <https://tip.tcl-lang.org/48.html>`_
|
||||
The Tcl Improvement Proposal that introduced the themed widget styling engine.
|
||||
|
||||
|
||||
Using Ttk
|
||||
@@ -47,21 +54,22 @@ That code causes several :mod:`!tkinter.ttk` widgets (:class:`Button`,
|
||||
:class:`Scrollbar` and :class:`Spinbox`) to
|
||||
automatically replace the Tk widgets.
|
||||
|
||||
.. note::
|
||||
|
||||
Overriding the classic widgets with ``from tkinter.ttk import *``
|
||||
is convenient for adapting existing code,
|
||||
but new code is usually clearer if it imports the module
|
||||
as ``from tkinter import ttk`` and refers to the themed widgets explicitly,
|
||||
such as ``ttk.Button``.
|
||||
|
||||
This has the direct benefit of using the new widgets which gives a better look
|
||||
and feel across platforms; however, the replacement widgets are not completely
|
||||
compatible.
|
||||
The main difference is that widget options such as "fg", "bg" and others
|
||||
The main difference is that widget options such as ``fg``, ``bg`` and others
|
||||
related to widget styling are no longer present in Ttk widgets.
|
||||
Instead, use the :class:`ttk.Style <Style>` class for improved styling effects.
|
||||
|
||||
|
||||
.. seealso::
|
||||
|
||||
`Converting existing applications to use Tile widgets <https://tktable.sourceforge.net/tile/doc/converting.txt>`_
|
||||
A monograph (using Tcl terminology) about differences typically
|
||||
encountered when moving applications to use the new widgets.
|
||||
|
||||
|
||||
Ttk widgets
|
||||
-----------
|
||||
|
||||
@@ -71,7 +79,7 @@ Ttk comes with 18 widgets, twelve of which already existed in tkinter:
|
||||
:class:`Radiobutton`, :class:`Scale`, :class:`Scrollbar`, and :class:`Spinbox`.
|
||||
The other six are new: :class:`Combobox`, :class:`Notebook`,
|
||||
:class:`Progressbar`, :class:`Separator`, :class:`Sizegrip` and
|
||||
:class:`Treeview`. And all them are subclasses of :class:`Widget`.
|
||||
:class:`Treeview`. All of them are subclasses of :class:`Widget`.
|
||||
|
||||
Using the Ttk widgets gives the application an improved look and feel.
|
||||
As discussed above, there are differences in how the styling is coded.
|
||||
@@ -1325,8 +1333,13 @@ If you don't know the class name of a widget, use the method
|
||||
|
||||
.. seealso::
|
||||
|
||||
`Tcl'2004 conference presentation <https://tktable.sourceforge.net/tile/tile-tcl2004.pdf>`_
|
||||
This document explains how the theme engine works
|
||||
`Introduction to the Tk theme engine <https://www.tcl-lang.org/man/tcl9.0/TkCmd/ttk_intro.html>`_
|
||||
The ``ttk::intro`` man page explains how the theme engine works.
|
||||
|
||||
`The Tile Widget Set <https://tktable.sourceforge.net/tile/tile-tcl2004.pdf>`_
|
||||
Joe English's 2004 paper introducing the theme engine
|
||||
(then the separate *Tile* extension),
|
||||
with diagrams of how elements and layouts make up a widget's appearance.
|
||||
|
||||
|
||||
.. class:: Style
|
||||
|
||||
Reference in New Issue
Block a user