Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 13 additions & 13 deletions Doc/library/tkinter.rst
Original file line number Diff line number Diff line change
Expand Up @@ -176,13 +176,13 @@

.. attribute:: master

The widget object that contains this widget. For :class:`Tk`, the

Check warning on line 179 in Doc/library/tkinter.rst

View workflow job for this annotation

GitHub Actions / Docs / Docs

py:meth reference target not found: winfo_parent [ref.meth]
*master* is :const:`None` because it is the main window. The terms
:attr:`!master` is :const:`None` because it is the main window. The terms
*master* and *parent* are similar and sometimes used interchangeably
as argument names; however, calling :meth:`winfo_parent` returns a
string of the widget name whereas :attr:`master` returns the object.
string of the widget name whereas :attr:`!master` returns the object.
*parent*/*child* reflects the tree-like relationship while
*master*/*slave* reflects the container structure.
*master* (or *container*)/*content* reflects the container structure.

.. attribute:: children

Expand Down Expand Up @@ -638,15 +638,15 @@
.. index:: 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 -
their mutual *master*. In contrast to the more cumbersome *placer* (which is
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.

The size of any *master* widget is determined by the size of the "slave widgets"
inside. The packer is used to control where slave widgets appear inside the
master into which they are packed. You can pack widgets into frames, and frames
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.
Expand All @@ -673,7 +673,7 @@
see the man pages and page 183 of John Ousterhout's book.

anchor
Anchor type. Denotes where the packer is to place each slave in its parcel.
Anchor type. Denotes where the packer is to place each content in its parcel.

expand
Boolean, ``0`` or ``1``.
Expand All @@ -682,10 +682,10 @@
Legal values: ``'x'``, ``'y'``, ``'both'``, ``'none'``.

ipadx and ipady
A distance - designating internal padding on each side of the slave widget.
A distance - designating internal padding on each side of the content.

padx and pady
A distance - designating external padding on each side of the slave widget.
A distance - designating external padding on each side of the content.

side
Legal values are: ``'left'``, ``'right'``, ``'top'``, ``'bottom'``.
Expand Down Expand Up @@ -757,9 +757,9 @@
subclassed from the :class:`Wm` class, and so can call the :class:`Wm` methods
directly.

To get at the toplevel window that contains a given widget, you can often just

Check warning on line 760 in Doc/library/tkinter.rst

View workflow job for this annotation

GitHub Actions / Docs / Docs

py:meth reference target not found: _root [ref.meth]

Check warning on line 760 in Doc/library/tkinter.rst

View workflow job for this annotation

GitHub Actions / Docs / Docs

py:attr reference target not found: master [ref.attr]
refer to the widget's master. Of course if the widget has been packed inside of
a frame, the master won't represent a toplevel window. To get at the toplevel
refer to the widget's :attr:`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:`_root` method.
This method begins with an underscore to denote the fact that this function is
part of the implementation, and not an interface to Tk functionality.
Expand Down
6 changes: 6 additions & 0 deletions Doc/whatsnew/3.15.rst
Original file line number Diff line number Diff line change
Expand Up @@ -792,6 +792,12 @@ tkinter
using Tcl's ``-all`` and ``-overlap`` options.
(Contributed by Rihaan Meher in :gh:`130848`)

* Added new methods :meth:`!pack_content`, :meth:`!place_content` and
:meth:`!grid_content` which use Tk commands with new names (introduced
in Tk 8.6) instead of :meth:`!*_slaves` methods which use Tk commands
with outdated names.
(Contributed by Serhiy Storchaka in :gh:`143754`)

types
------

Expand Down
66 changes: 50 additions & 16 deletions Lib/test/test_tkinter/test_geometry_managers.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,11 @@ def test_pack_configure_after(self):
b.pack_configure(side='top')
c.pack_configure(side='top')
d.pack_configure(side='top')
self.assertEqual(pack.pack_slaves(), [a, b, c, d])
self.assertEqual(pack.pack_content(), [a, b, c, d])
a.pack_configure(after=b)
self.assertEqual(pack.pack_slaves(), [b, a, c, d])
self.assertEqual(pack.pack_content(), [b, a, c, d])
a.pack_configure(after=a)
self.assertEqual(pack.pack_slaves(), [b, a, c, d])
self.assertEqual(pack.pack_content(), [b, a, c, d])

def test_pack_configure_anchor(self):
pack, a, b, c, d = self.create2()
Expand Down Expand Up @@ -72,11 +72,11 @@ def test_pack_configure_before(self):
b.pack_configure(side='top')
c.pack_configure(side='top')
d.pack_configure(side='top')
self.assertEqual(pack.pack_slaves(), [a, b, c, d])
self.assertEqual(pack.pack_content(), [a, b, c, d])
a.pack_configure(before=d)
self.assertEqual(pack.pack_slaves(), [b, c, a, d])
self.assertEqual(pack.pack_content(), [b, c, a, d])
a.pack_configure(before=a)
self.assertEqual(pack.pack_slaves(), [b, c, a, d])
self.assertEqual(pack.pack_content(), [b, c, a, d])

def test_pack_configure_expand(self):
pack, a, b, c, d = self.create2()
Expand Down Expand Up @@ -109,10 +109,10 @@ def test_pack_configure_in(self):
c.pack_configure(side='top')
d.pack_configure(side='top')
a.pack_configure(in_=pack)
self.assertEqual(pack.pack_slaves(), [b, c, d, a])
self.assertEqual(pack.pack_content(), [b, c, d, a])
a.pack_configure(in_=c)
self.assertEqual(pack.pack_slaves(), [b, c, d])
self.assertEqual(c.pack_slaves(), [a])
self.assertEqual(pack.pack_content(), [b, c, d])
self.assertEqual(c.pack_content(), [a])
with self.assertRaisesRegex(
TclError, """can't pack "?%s"? inside itself""" % (a,)):
a.pack_configure(in_=a)
Expand Down Expand Up @@ -222,11 +222,11 @@ def test_pack_forget(self):
a.pack_configure()
b.pack_configure()
c.pack_configure()
self.assertEqual(pack.pack_slaves(), [a, b, c])
self.assertEqual(pack.pack_content(), [a, b, c])
b.pack_forget()
self.assertEqual(pack.pack_slaves(), [a, c])
self.assertEqual(pack.pack_content(), [a, c])
b.pack_forget()
self.assertEqual(pack.pack_slaves(), [a, c])
self.assertEqual(pack.pack_content(), [a, c])
d.pack_forget()

def test_pack_info(self):
Expand Down Expand Up @@ -272,6 +272,14 @@ def test_pack_propagate(self):
self.assertEqual(pack.winfo_reqwidth(), 20)
self.assertEqual(pack.winfo_reqheight(), 40)

def test_pack_content(self):
pack, a, b, c, d = self.create2()
self.assertEqual(pack.pack_content(), [])
a.pack_configure()
self.assertEqual(pack.pack_content(), [a])
b.pack_configure()
self.assertEqual(pack.pack_content(), [a, b])

def test_pack_slaves(self):
pack, a, b, c, d = self.create2()
self.assertEqual(pack.pack_slaves(), [])
Expand Down Expand Up @@ -476,6 +484,15 @@ def test_place_info(self):
with self.assertRaises(TypeError):
f2.place_info(0)

def test_place_content(self):
foo = tkinter.Frame(self.root)
bar = tkinter.Frame(self.root)
self.assertEqual(foo.place_content(), [])
bar.place_configure(in_=foo)
self.assertEqual(foo.place_content(), [bar])
with self.assertRaises(TypeError):
foo.place_content(0)

def test_place_slaves(self):
foo = tkinter.Frame(self.root)
bar = tkinter.Frame(self.root)
Expand Down Expand Up @@ -728,10 +745,10 @@ def test_grid_forget(self):
c = tkinter.Button(self.root)
b.grid_configure(row=2, column=2, rowspan=2, columnspan=2,
padx=3, pady=4, sticky='ns')
self.assertEqual(self.root.grid_slaves(), [b])
self.assertEqual(self.root.grid_content(), [b])
b.grid_forget()
c.grid_forget()
self.assertEqual(self.root.grid_slaves(), [])
self.assertEqual(self.root.grid_content(), [])
self.assertEqual(b.grid_info(), {})
b.grid_configure(row=0, column=0)
info = b.grid_info()
Expand All @@ -748,10 +765,10 @@ def test_grid_remove(self):
c = tkinter.Button(self.root)
b.grid_configure(row=2, column=2, rowspan=2, columnspan=2,
padx=3, pady=4, sticky='ns')
self.assertEqual(self.root.grid_slaves(), [b])
self.assertEqual(self.root.grid_content(), [b])
b.grid_remove()
c.grid_remove()
self.assertEqual(self.root.grid_slaves(), [])
self.assertEqual(self.root.grid_content(), [])
self.assertEqual(b.grid_info(), {})
b.grid_configure(row=0, column=0)
info = b.grid_info()
Expand Down Expand Up @@ -886,6 +903,23 @@ def test_grid_size(self):
f.grid_configure(row=4, column=5)
self.assertEqual(self.root.grid_size(), (6, 5))

def test_grid_content(self):
self.assertEqual(self.root.grid_content(), [])
a = tkinter.Label(self.root)
a.grid_configure(row=0, column=1)
b = tkinter.Label(self.root)
b.grid_configure(row=1, column=0)
c = tkinter.Label(self.root)
c.grid_configure(row=1, column=1)
d = tkinter.Label(self.root)
d.grid_configure(row=1, column=1)
self.assertEqual(self.root.grid_content(), [d, c, b, a])
self.assertEqual(self.root.grid_content(row=0), [a])
self.assertEqual(self.root.grid_content(row=1), [d, c, b])
self.assertEqual(self.root.grid_content(column=0), [b])
self.assertEqual(self.root.grid_content(column=1), [d, c, a])
self.assertEqual(self.root.grid_content(row=1, column=1), [d, c])

def test_grid_slaves(self):
self.assertEqual(self.root.grid_slaves(), [])
a = tkinter.Label(self.root)
Expand Down
Loading
Loading