Tkinter is a relatively thin wrapper around the Tcl/Tk library. It automatically translates Python objects to corresponding Tcl values and back, although in some cases it needs a code to ensure the structure of the returned values, because in Tcl "foo bar"
, ("foo", "bar")
and {"foo": "bar"}
can be the same. Tcl as the programming language does not have keyword arguments, but there is a convention that options are passed as intermixed minus-prefixed names and values. Tkinter usually translates keyword arguments to Tcl options.
For example, Tcl/Tk command .b configure -padding {2 0 0 2}
corresponds to Python call b.configure(padding=(2, 0, 0, 2))
. And while Tcl/Tk command .b configure
returns
{-command command Command {} {}} {-default default Default normal normal} {-takefocus takeFocus TakeFocus ttk::takefocus ttk::takefocus} {-text text Text {} {}} {-textvariable textVariable Variable {} {}} {-underline underline Underline -1 -1} {-width width Width {} {}} {-image image Image {} {}} {-compound compound Compound {} {}} {-padding padding Pad {} {}} {-state state State normal normal} {-cursor cursor Cursor {} {}} {-style style Style {} {}} {-class {} {} {} {}}
which can be automatically translated in Python as
(('-command', 'command', 'Command', '', ''), ('-default', 'default', 'Default', <index object: 'normal'>, <index object: 'normal'>), ('-takefocus', 'takeFocus', 'TakeFocus', 'ttk::takefocus', 'ttk::takefocus'), ('-text', 'text', 'Text', '', ''), ('-textvariable', 'textVariable', 'Variable', '', ''), ('-underline', 'underline', 'Underline', -1, -1), ('-width', 'width', 'Width', '', ''), ('-image', 'image', 'Image', '', ''), ('-compound', 'compound', 'Compound', '', ''), ('-padding', 'padding', 'Pad', '', ''), ('-state', 'state', 'State', <index object: 'normal'>, <index object: 'normal'>), ('-cursor', 'cursor', 'Cursor', '', ''), ('-style', 'style', 'Style', '', ''), ('-class', '', '', '', ''))
the wrapper makes Python call b.configure()
returning a dict
{'command': ('command', 'command', 'Command', '', ''), 'default': ('default', 'default', 'Default', <index object: 'normal'>, <index object: 'normal'>), 'takefocus': ('takefocus', 'takeFocus', 'TakeFocus', 'ttk::takefocus', 'ttk::takefocus'), 'text': ('text', 'text', 'Text', '', ''), 'textvariable': ('textvariable', 'textVariable', 'Variable', '', ''), 'underline': ('underline', 'underline', 'Underline', -1, -1), 'width': ('width', 'width', 'Width', '', ''), 'image': ('image', 'image', 'Image', '', ''), 'compound': ('compound', 'compound', 'Compound', '', ''), 'padding': ('padding', 'padding', 'Pad', '', ''), 'state': ('state', 'state', 'State', <index object: 'normal'>, <index object: 'normal'>), 'cursor': ('cursor', 'cursor', 'Cursor', '', ''), 'style': ('style', 'style', 'Style', '', ''), 'class': ('class', '', '', '', '')}
But it all was not done in the wm_attributes()
method. To pass options you need to call w.wm_attributes('-alpha', 0.5, '-type', 'dialog')
instead of more Pythonic w.wm_attributes(alpha= 0.5, type='dialog')
. Well, it is easy part, we can do both of them working. The hard part is that currently w.wm_attributes()
without arguments returns a tuple (or even a str when wantobjects was set to 0), e.g. ('-alpha', 1.0, '-topmost', 0, '-zoomed', 0, '-fullscreen', 0, '-type', '')
. It is difficult to use and differs from virtually all other methods. It would be better to return a dict {'alpha': 1.0, 'topmost': 0, 'zoomed': 0, 'fullscreen': 0, 'type': ''}
.
But it is a breaking change! For @tjreedy’s suggestion I ask the Steering Сouncil permission to make such change. Deprecation period is not possible, because the result should be a dict or a tuple, not both. Fortunately, None
passed as argument is ignored in the current implementation, and it can be used as a sign to return the old value, so if you do not have time to rewrite the code that works with the returned value, you can simply pass None
as argument: w.wm_attributes(None)
.
For details see the issue:
And the PR: