mirror of https://github.com/python/cpython
gh-43457: Tkinter: fix design flaws in wm_attributes() (GH-111404)
* When called with a single argument to get a value, it allow to omit the minus prefix. * It can be called with keyword arguments to set attributes. * w.wm_attributes(return_python_dict=True) returns a dict instead of a tuple (it will be the default in future). * Setting wantobjects to 0 no longer affects the result.
This commit is contained in:
parent
992446dd5b
commit
b4ba0f73d6
|
@ -421,6 +421,15 @@ tkinter
|
|||
:meth:`!tk_busy_current`, and :meth:`!tk_busy_status`.
|
||||
(Contributed by Miguel, klappnase and Serhiy Storchaka in :gh:`72684`.)
|
||||
|
||||
* The :mod:`tkinter` widget method :meth:`!wm_attributes` now accepts
|
||||
the attribute name without the minus prefix to get window attributes,
|
||||
e.g. ``w.wm_attributes('alpha')`` and allows to specify attributes and
|
||||
values to set as keyword arguments, e.g. ``w.wm_attributes(alpha=0.5)``.
|
||||
Add new optional keyword-only parameter *return_python_dict*: calling
|
||||
``w.wm_attributes(return_python_dict=True)`` returns the attributes as
|
||||
a dict instead of a tuple.
|
||||
(Contributed by Serhiy Storchaka in :gh:`43457`.)
|
||||
|
||||
* Add support of the "vsapi" element type in
|
||||
the :meth:`~tkinter.ttk.Style.element_create` method of
|
||||
:class:`tkinter.ttk.Style`.
|
||||
|
|
|
@ -14,7 +14,7 @@ class AbstractTkTest:
|
|||
# Some window managers can maximize new windows.
|
||||
cls.root.wm_state('normal')
|
||||
try:
|
||||
cls.root.wm_attributes('-zoomed', False)
|
||||
cls.root.wm_attributes(zoomed=False)
|
||||
except tkinter.TclError:
|
||||
pass
|
||||
|
||||
|
|
|
@ -437,6 +437,61 @@ class MiscTest(AbstractTkTest, unittest.TestCase):
|
|||
self.assertTrue(str(vi).startswith(f'{vi.major}.{vi.minor}'))
|
||||
|
||||
|
||||
class WmTest(AbstractTkTest, unittest.TestCase):
|
||||
|
||||
def test_wm_attribute(self):
|
||||
w = self.root
|
||||
attributes = w.wm_attributes(return_python_dict=True)
|
||||
self.assertIsInstance(attributes, dict)
|
||||
attributes2 = w.wm_attributes()
|
||||
self.assertIsInstance(attributes2, tuple)
|
||||
self.assertEqual(attributes2[::2],
|
||||
tuple('-' + k for k in attributes))
|
||||
self.assertEqual(attributes2[1::2], tuple(attributes.values()))
|
||||
# silently deprecated
|
||||
attributes3 = w.wm_attributes(None)
|
||||
if self.wantobjects:
|
||||
self.assertEqual(attributes3, attributes2)
|
||||
else:
|
||||
self.assertIsInstance(attributes3, str)
|
||||
|
||||
for name in attributes:
|
||||
self.assertEqual(w.wm_attributes(name), attributes[name])
|
||||
# silently deprecated
|
||||
for name in attributes:
|
||||
self.assertEqual(w.wm_attributes('-' + name), attributes[name])
|
||||
|
||||
self.assertIn('alpha', attributes)
|
||||
self.assertIn('fullscreen', attributes)
|
||||
self.assertIn('topmost', attributes)
|
||||
if w._windowingsystem == "win32":
|
||||
self.assertIn('disabled', attributes)
|
||||
self.assertIn('toolwindow', attributes)
|
||||
self.assertIn('transparentcolor', attributes)
|
||||
if w._windowingsystem == "aqua":
|
||||
self.assertIn('modified', attributes)
|
||||
self.assertIn('notify', attributes)
|
||||
self.assertIn('titlepath', attributes)
|
||||
self.assertIn('transparent', attributes)
|
||||
if w._windowingsystem == "x11":
|
||||
self.assertIn('type', attributes)
|
||||
self.assertIn('zoomed', attributes)
|
||||
|
||||
w.wm_attributes(alpha=0.5)
|
||||
self.assertEqual(w.wm_attributes('alpha'),
|
||||
0.5 if self.wantobjects else '0.5')
|
||||
w.wm_attributes(alpha=1.0)
|
||||
self.assertEqual(w.wm_attributes('alpha'),
|
||||
1.0 if self.wantobjects else '1.0')
|
||||
# silently deprecated
|
||||
w.wm_attributes('-alpha', 0.5)
|
||||
self.assertEqual(w.wm_attributes('alpha'),
|
||||
0.5 if self.wantobjects else '0.5')
|
||||
w.wm_attributes(alpha=1.0)
|
||||
self.assertEqual(w.wm_attributes('alpha'),
|
||||
1.0 if self.wantobjects else '1.0')
|
||||
|
||||
|
||||
class BindTest(AbstractTkTest, unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
|
|
|
@ -2108,26 +2108,39 @@ class Wm:
|
|||
|
||||
aspect = wm_aspect
|
||||
|
||||
def wm_attributes(self, *args):
|
||||
"""This subcommand returns or sets platform specific attributes
|
||||
def wm_attributes(self, *args, return_python_dict=False, **kwargs):
|
||||
"""Return or sets platform specific attributes.
|
||||
|
||||
The first form returns a list of the platform specific flags and
|
||||
their values. The second form returns the value for the specific
|
||||
option. The third form sets one or more of the values. The values
|
||||
are as follows:
|
||||
When called with a single argument return_python_dict=True,
|
||||
return a dict of the platform specific attributes and their values.
|
||||
When called without arguments or with a single argument
|
||||
return_python_dict=False, return a tuple containing intermixed
|
||||
attribute names with the minus prefix and their values.
|
||||
|
||||
On Windows, -disabled gets or sets whether the window is in a
|
||||
disabled state. -toolwindow gets or sets the style of the window
|
||||
to toolwindow (as defined in the MSDN). -topmost gets or sets
|
||||
whether this is a topmost window (displays above all other
|
||||
windows).
|
||||
|
||||
On Macintosh, XXXXX
|
||||
|
||||
On Unix, there are currently no special attribute values.
|
||||
When called with a single string value, return the value for the
|
||||
specific option. When called with keyword arguments, set the
|
||||
corresponding attributes.
|
||||
"""
|
||||
args = ('wm', 'attributes', self._w) + args
|
||||
return self.tk.call(args)
|
||||
if not kwargs:
|
||||
if not args:
|
||||
res = self.tk.call('wm', 'attributes', self._w)
|
||||
if return_python_dict:
|
||||
return _splitdict(self.tk, res)
|
||||
else:
|
||||
return self.tk.splitlist(res)
|
||||
if len(args) == 1 and args[0] is not None:
|
||||
option = args[0]
|
||||
if option[0] == '-':
|
||||
# TODO: deprecate
|
||||
option = option[1:]
|
||||
return self.tk.call('wm', 'attributes', self._w, '-' + option)
|
||||
# TODO: deprecate
|
||||
return self.tk.call('wm', 'attributes', self._w, *args)
|
||||
elif args:
|
||||
raise TypeError('wm_attribute() options have been specified as '
|
||||
'positional and keyword arguments')
|
||||
else:
|
||||
self.tk.call('wm', 'attributes', self._w, *self._options(kwargs))
|
||||
|
||||
attributes = wm_attributes
|
||||
|
||||
|
|
|
@ -262,7 +262,7 @@ def _setup_dialog(w):
|
|||
w.tk.call("::tk::unsupported::MacWindowStyle", "style",
|
||||
w, "moveableModal", "")
|
||||
elif w._windowingsystem == "x11":
|
||||
w.wm_attributes("-type", "dialog")
|
||||
w.wm_attributes(type="dialog")
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# convenience dialogues
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
Fix the :mod:`tkinter` widget method :meth:`!wm_attributes`. It now
|
||||
accepts the attribute name without the minus prefix to get window attributes
|
||||
and allows to specify attributes and values to set as keyword arguments.
|
||||
Add new optional keyword argument *return_python_dict*: calling
|
||||
``w.wm_attributes(return_python_dict=True)`` returns the attributes as
|
||||
a dict instead of a tuple.
|
||||
Calling ``w.wm_attributes()`` now returns a tuple instead of string if
|
||||
*wantobjects* was set to 0.
|
Loading…
Reference in New Issue