homepage

This issue tracker has been migrated to GitHub , and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: tkinter: Canvas().keys returns empty strings.
Type: behavior Stage: resolved
Components: Library (Lib), Tkinter Versions: Python 3.6, Python 3.5, Python 2.7
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: serhiy.storchaka Nosy List: python-dev, serhiy.storchaka, terry.reedy
Priority: normal Keywords: patch

Created on 2016年01月22日 06:51 by terry.reedy, last changed 2022年04月11日 14:58 by admin. This issue is now closed.

Files
File name Uploaded Description Edit
tkinter_keys.patch serhiy.storchaka, 2016年01月22日 11:05 review
Messages (6)
msg258789 - (view) Author: Terry J. Reedy (terry.reedy) * (Python committer) Date: 2016年01月22日 06:51
tkinter wraps tk widgets as option-value mappings with subscripting and .keys(). The latter does not work for Canvas (subscripting does). First tested with 3.5.1, Win 10. First Text versus Canvas contrast below was confirmed with 2.7.11.
>>> import tkinter as tk
>>> tk.Text().keys()
['autoseparators', 'background', 'bd', 'bg', 'blockcursor', 'tabstyle', 
...
'takefocus', 'undo', 'width', 'wrap', 'xscrollcommand', 'yscrollcommand']
>>> tk.Canvas().keys()
['', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '']
Explanation: Widget classes inherit keys from Misc via BaseWidget and Widget. Misc.keys calls into tk.
 def keys(self):
 """Return a list of all resource names of this widget."""
 return [x[0][1:] for x in
 self.tk.splitlist(self.tk.call(self._w, 'configure'))]
The call returns different types for Text and Canvas.
>>> self = tk.Text()
>>> self.tk.call(self._w, 'configure') # tuple of tuples
(('-autoseparators', 'autoSeparators', 'AutoSeparators', 1, 1),
 ('-background', 'background', 'Background', <border object: 'SystemWindow'>, 'SystemWindow'), <etc>)
>>> self = tk.Canvas()
>>> self.tk.call(self._w, 'configure') # tcl list as single string
'{-background background Background SystemButtonFace SystemButtonFace} {-bd borderWidth} {-bg background} {-borderwidth borderWidth BorderWidth 0 0} ...'
This difference between widgets seems odd. A bug in tcl/tk/_tkinter?
tk.splitlist appears to return the Text tuple of tuples as is. It splits the Canvas string into a tuple of strings
('-background background Background SystemButtonFace SystemButtonFace', '-bd borderWidth', ... )
but does not split the inner strings. As a consequence, x[0] is the first character of each string ('{' as it turns out, though not relevant) and the slice [1:] of a single char string is always ''.
Possible remedy: tk.split also leaves tuple of tuples alone *and* splits the inner strings to a tuple.
>>> self.tk.split(self.tk.call(self._w, 'configure'))
(('-background', 'background', 'Background', 'SystemButtonFace', 'red'), ('-bd', 'borderWidth'), ...)
So a fix (if the different returns are not changed) is to change 'splitlines' to 'split'. With this change, keys (extracted as a function) gives the expected list.
>>> keys(tk.Canvas())
['background', 'bd', ..., 'yscrollincrement']
A test for Canvas().keys should be added somewhere.
msg258790 - (view) Author: Terry J. Reedy (terry.reedy) * (Python committer) Date: 2016年01月22日 07:02
Bug came from https://stackoverflow.com/questions/34911069/tk-canvas-options-keys-list-empy. Bryan Oakley answered that tk.Canvas().configure().keys() does work, making sorted(x.configure.keys()) a replacement for x.keys that should work for all widgets.
msg258791 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2016年01月22日 11:05
split() has many warts, it shouldn't be used. It is enough just call splitlist() for elements of a list.
Proposed patch fixes Misc.keys(). It also adds tests for missed options (some of them are not explicitly documented).
msg258843 - (view) Author: Terry J. Reedy (terry.reedy) * (Python committer) Date: 2016年01月22日 23:28
With patch applied to 3.5, tk.Canvas().keys() works and test_tk and other three files pass with -ugui.
Is avoiding splitlist calls when not needed worthwhile? Tests also pass with 
 def keys(self):
 """Return a list of all resource names of this widget."""
 config = self.tk.call(self._w, 'configure')
 if type(config) == tuple:
 return [x[0][1:] for x in config]
 else: # str
 splitlist = self.tk.splitlist
 return [splitlist(x)[0][1:] for x in
 splitlist(config)]
I am a bit curious why Canvas gives a different return. Is the special casing in _tkinter or tk itself? Otherwise, looks good to me.
msg258856 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2016年01月23日 09:33
> Is avoiding splitlist calls when not needed worthwhile?
We can't guarantee that future release of Tk wouldn't return a list of strings. Calling splitlist() for a tuple is cheap (but looks cumbersome).
> I am a bit curious why Canvas gives a different return. Is the special casing in _tkinter or tk itself?
Tk is full of such inconsistencies. A result for one widget can be a list of numbers, but for other it is a list of strings or a list of special Tcl objects. One method can return empty list, other returns empty string. One widgets truncate floating point parameters, others round them up or down.
I'll commit the patch after testing with Tk 8.5 and 8.4.
msg261407 - (view) Author: Roundup Robot (python-dev) (Python triager) Date: 2016年03月09日 08:52
New changeset d86891dee68a by Serhiy Storchaka in branch '3.5':
Issue #26177: Fixed the keys() method for Canvas and Scrollbar widgets.
https://hg.python.org/cpython/rev/d86891dee68a
New changeset f0c895fb0374 by Serhiy Storchaka in branch '2.7':
Issue #26177: Fixed the keys() method for Canvas and Scrollbar widgets.
https://hg.python.org/cpython/rev/f0c895fb0374
New changeset 3a0bc2efed26 by Serhiy Storchaka in branch 'default':
Issue #26177: Fixed the keys() method for Canvas and Scrollbar widgets.
https://hg.python.org/cpython/rev/3a0bc2efed26 
History
Date User Action Args
2022年04月11日 14:58:26adminsetgithub: 70365
2016年03月09日 08:55:11serhiy.storchakasetstatus: open -> closed
resolution: fixed
stage: commit review -> resolved
2016年03月09日 08:52:44python-devsetnosy: + python-dev
messages: + msg261407
2016年01月23日 09:33:44serhiy.storchakasetmessages: + msg258856
2016年01月22日 23:28:21terry.reedysetmessages: + msg258843
stage: patch review -> commit review
2016年01月22日 11:06:01serhiy.storchakasetfiles: + tkinter_keys.patch
keywords: + patch
messages: + msg258791

components: + Library (Lib), Tkinter
2016年01月22日 08:48:48serhiy.storchakasetassignee: serhiy.storchaka
2016年01月22日 07:02:48terry.reedysetmessages: + msg258790
2016年01月22日 06:51:29terry.reedycreate

AltStyle によって変換されたページ (->オリジナル) /