classification
Title: tkinter - Treeview - .selection_add and selection_toggle
Type: behavior Stage: resolved
Components: Tkinter Versions: Python 3.6, Python 3.5, Python 2.7
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: serhiy.storchaka Nosy List: gbarnabic, ned.deily, python-dev, serhiy.storchaka, terry.reedy
Priority: normal Keywords: patch

Created on 2016-02-18 16:30 by gbarnabic, last changed 2019-02-24 08:07 by ned.deily. This issue is now closed.

Files
File name Uploaded Description Edit
ttk_treeview_selection.patch serhiy.storchaka, 2016-02-24 09:57 review
Pull Requests
URL Status Linked Edit
PR 12014 merged ned.deily, 2019-02-24 07:54
Messages (8)
msg260469 - (view) Author: George (gbarnabic) Date: 2016-02-18 16:30
Id's with spaces in them causes a crash when using the .selection* methods Treeview.  Version of ttk.py "0.3.1" dated 12/6/2015.  Traceback line numbers are 1415 then 1395  

Either of these lines of code, where the item id is "2009 Report.pdf" crash
   allParents = oTree.get_children()
   for id in allParents:
     oTree.selection_add(id)
     #  oTree.selection_toggle(id)

These two lines of workaround code do work however.
   oTree.selection_add('"' + id + '"')
   #  oTree.selection_toggle('"' + id + '"')

Note that so far all other places in dealing with the item id's have no issue when there are spaces in them.
msg260553 - (view) Author: Terry J. Reedy (terry.reedy) * (Python committer) Date: 2016-02-20 03:44
The 3.5 version of 2015 Dec 6 is 3.5.1. A traceback is not a crash for the purpose of this tracker.

It is generally a good idea to mention OS, OS version, and Tk Version. (IDLE displays TkVersion in Help => About IDLE.)  However, on Win 10 (8.6.4), I was able to reproduce with all four of the .selection_xyz(items) methods, which are all specializations of the .selection(op, items) methods.

import tkinter as tk
from tkinter import ttk
root = tk.Tk()
tree = ttk.Treeview(root)
tree.pack()
tree.insert('', 1, iid='a b', text='id with space')
for item in tree.get_children():
    print(item)
    #tree.selection_add(item)  # fail
    #tree.selection_toggle(item)  # fail
    #tree.selection_set(item)  # fail
    #tree.selection_remove(item)  # fail
    tree.selection('add', item)  # fail

getting

a b
Traceback (most recent call last):
  File "F:\Python\mypy\tem.py", line 10, in <module>
    tree.selection_toggle(item)
  File "C:\Programs\Python35\lib\tkinter\ttk.py", line 1415, in selection_toggle
    self.selection("toggle", items)
  File "C:\Programs\Python35\lib\tkinter\ttk.py", line 1395, in selection
    return self.tk.call(self._w, "selection", selop, items)
_tkinter.TclError: Item a not found

tkinter 


These are the only Treeview methods in which a single argument can be multiple items.  The doc string and doc do not define the form of 'items'.  The unofficial but generally helpful doc, http://infohost.nmt.edu/tcc/help/pubs/tkinter/web/ttk-Treeview.html says "The argument may be either a single iid or a sequence of iids."  I would expect sequence mean a tuple of strings, not space-separated fields in a string (a tcl sequence).

The .delete and .detach methods have signature '*items', meaning that each item is passed as a separate argument.  The methods them pass the tuple of strings to tk.  This should have been the signature of the selection methods.

Putting a single string in a tuple solves the problem, as in.

    tree.selection('add', (item,))

My suggested fix is to add a statement to .selection

    def selection(self, selop=None, items=None):
        """If selop is not specified, returns selected items."""
        if isinstance(items, str):  # new
            items = (items,)
        return self.tk.call(self._w, "selection", selop, items)
msg260780 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2016-02-24 09:57
Here is the patch with tests.

But I like the idea to make the selection_*() methods conforming with the delete() and detach() methods in 3.6.
msg268470 - (view) Author: Terry J. Reedy (terry.reedy) * (Python committer) Date: 2016-06-13 20:23
LGTM, but after applying to all 3, leave open (or open new issue) to replace patch in 3.6  (before beta 1).

Change signature to *items.  That will automatically make a single string become a len 1 tuple.  For selection (list the 4 selops and) add a note.  "For back compatibility, one may also pass a single tuple (or list?) of items." and Version Changed.  For 4 derivatives, 'See selection.' In the code, instead add (untested):

    if len(items) == 1:  # Remove after deprecation.
        item0 = items[0]
        if not isinstance(items[0], isinstance(str)):
            raise DeprecationWarning(
                 <level arg>
                 "The option of passing multiple items as a tuple "
                 "rather than as multiple items is deprecated and "
                 "will be removed in 2020 or later.")
            items = items0  # or more processing if lists were allowed

Revise test accordingly.
msg268547 - (view) Author: Roundup Robot (python-dev) (Python triager) Date: 2016-06-14 09:46
New changeset 0885477fecfd by Serhiy Storchaka in branch '3.5':
Issue #26386: Fixed ttk.TreeView selection operations with item id's
https://hg.python.org/cpython/rev/0885477fecfd

New changeset d1c0bc1d0625 by Serhiy Storchaka in branch 'default':
Issue #26386: Fixed ttk.TreeView selection operations with item id's
https://hg.python.org/cpython/rev/d1c0bc1d0625

New changeset ac7c10f5e36e by Serhiy Storchaka in branch '2.7':
Issue #26386: Fixed ttk.TreeView selection operations with item id's
https://hg.python.org/cpython/rev/ac7c10f5e36e
msg268575 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2016-06-14 17:42
Thank you Terry.

Opened issue27319 for changing the signature of selection methods.
msg336446 - (view) Author: Ned Deily (ned.deily) * (Python committer) Date: 2019-02-24 08:04
New changeset 72ff2f7554e550762acaad805a8a0d456a29468a by Ned Deily in branch '2.7':
bpo-26386: Re-enable missing widget testcases in test_ttk_guionly. (GH-12014)
https://github.com/python/cpython/commit/72ff2f7554e550762acaad805a8a0d456a29468a
msg336448 - (view) Author: Ned Deily (ned.deily) * (Python committer) Date: 2019-02-24 08:07
It looks like some testing code was inadvertently committed in the 2.7 branch fix causing only the Treeview testcases to be executed when test_ttk_gui_only is run. (I noticed this because a testcase was failing on other branches but not 2.7 although the tests are virtually identical.)  PR 12014 fixes this.
History
Date User Action Args
2019-02-24 08:07:19ned.deilysetmessages: + msg336448
2019-02-24 08:04:21ned.deilysetnosy: + ned.deily
messages: + msg336446
2019-02-24 07:54:26ned.deilysetpull_requests: + pull_request12045
2016-06-14 17:42:33serhiy.storchakasetstatus: open -> closed
messages: + msg268575

assignee: serhiy.storchaka
resolution: fixed
stage: commit review -> resolved
2016-06-14 09:46:48python-devsetnosy: + python-dev
messages: + msg268547
2016-06-13 20:23:09terry.reedysetmessages: + msg268470
stage: patch review -> commit review
2016-02-24 10:23:17anish.shahsetnosy: - anish.shah
2016-02-24 09:57:22serhiy.storchakasetfiles: + ttk_treeview_selection.patch
keywords: + patch
messages: + msg260780

stage: test needed -> patch review
2016-02-20 03:45:17terry.reedysetstage: test needed
versions: + Python 2.7, Python 3.6
2016-02-20 03:44:14terry.reedysetnosy: + serhiy.storchaka, terry.reedy
type: crash -> behavior
messages: + msg260553
2016-02-18 18:44:00anish.shahsetnosy: + anish.shah
2016-02-18 16:30:08gbarnabiccreate