[Python-Dev] ttk.Treeview.insert() does not allow to insert item with iid=0

Terry Reedy tjreedy at udel.edu
Fri Mar 16 16:22:20 EDT 2018

On 3/16/2018 6:54 AM, Игорь Яковченко wrote:

This might fit python-list better, and may become a bugs.python.org 
issue, but I will answer now, having just investigated.

> I found a possible bug with ttk.Treeview widget.

See below.

> I'm working on program that uses tkinter UI. I use ttk.Treeview to 
> display some objects and I want to use integer iid of items.

For tk, the underlying graphics framework, iids are strings.  "If iid is 
specified, it is used as the item identifier", from the Treeview doc, 
oversimplifies.  When iid is specified, the iid used internally and 
returned by Treeview() is a string based on the value passed.  1 becomes 
'1', 1.0 becomes '1.0', (1,2,3) and [1,2,3] both become '1 2 3' (this is 
consistent in tkinter), and int becomes "<class 'int'>".  Since the 
transformation is the same when referencing an item, as with 
tv.index(iid), one can usually ignore it.  But it shows up if one prints 
a return value (as I did to discover the above), or tries to compare it 
with the original objects, or tries to use two different objects with 
the same tk string as iids.

> For example, I insert a row with treeview.insert(... iid=0, ...).
> But I 
> encountered a problem when I try to get this item from treeview by iid 
> when iid =0.

Other things being equal, I agree that one should be able to pass 0 and 
0.0 along with all other ints and floats. In the meanwhile, you could 
pass '0' and retrieve with either '0' or 0.  To not special-case 0, 
always pass iid=int(row).

> There is no item with such iid. This item has autogenerated iid just 
> like it's not specified.
> I investigated problem and found that in ttk.py, Treeview.insert(... 
> iid=None, ...) in method's body has a check:
>          if iid:
>              res = self.tk.call(self._w, "insert", parent, index,
>                  "-id", iid, *opts)
>          else:
>              res = self.tk.call(self._w, "insert", parent, index, *opts)
> It means that if iid is "True" then use it else autogenerate it.
> Maybe there should be "if iid is not None", not "if iid"? Or there are 
> some reasons to do check this way?

It might be that accepting '' as an iid would be a problem.
Our current tkinter expert, Serhiy Storchaka, should know.  If so, "if 
iid in (None, '')" would be needed.

Terry Jan Reedy

More information about the Python-Dev mailing list