I encounter untoward behavior when querying the open
option of a (Python) ttk.Treeview
item
. The visibility of a node (item
) can be set by doing something like:
tree.item(someItemID, open=True) # or
tree.item(someItemID, open=False)
And my assumption is the open
option can be queried to get a boolean True/False. However, this doesn't appear to be the case. Consider this script:
from Tkinter import *
from ttk import Treeview
def check_state():
for row in tree.get_children():
opened = tree.item(row, option='open')
print row, 'opened:', opened, '(type: %s)' % str(type(opened)), 'Got:',
if not opened:
print 'False (bool)'
elif opened == 'true':
print 'equal to string "true"'
elif opened == 'false':
print 'equal to string "false"'
elif opened:
print 'True (bool)'
else:
print 'something entirely different(!)'
print
win = Frame()
tree = Treeview(win)
win.pack()
tree.pack()
Button(win, text='View state', command=check_state).pack()
level1 = ['C:\\dir1', 'C:\\dir2', 'C:\\dir3']
level2 = ['one.txt', 'two.txt', 'three.txt']
for L in level1:
iid = tree.insert('', END, text=L)
for M in level2:
tree.insert(iid, END, text=M)
win.mainloop()
When run, it displays a small Treeview control populated with fake directories and file names. Before opening or closing any of the top-level nodes, press the button to dump the open
option states to stdout. Should look like this:
I001 opened: 0 (type: <type 'int'>) Got: False (bool)
I005 opened: 0 (type: <type 'int'>) Got: False (bool)
I009 opened: 0 (type: <type 'int'>) Got: False (bool)
Now open one of the nodes and press the button again. Now it dumps:
I001 opened: 0 (type: <type 'int'>) Got: False (bool)
I005 opened: 0 (type: <type 'int'>) Got: False (bool)
I009 opened: true (type: <type '_tkinter.Tcl_Obj'>) Got: True (bool)
Finally, close all nodes and press the button once more. It dumps:
I001 opened: 0 (type: <type 'int'>) Got: False (bool)
I005 opened: 0 (type: <type 'int'>) Got: False (bool)
I009 opened: false (type: <type '_tkinter.Tcl_Obj'>) Got: True (bool)
Things that stand out to me:
- Inconsistency: while initialized to
int
s, later the values assigned are_tkinter
objects - Boolean comparison failure: despite the
_tkinter
objects rendering as the strings 'true' or 'false' they do not evaluate to True and False (e.g. the_tkinter
object printed as "false" evaluated as True)
Anyone know what gives? How can I reliably determine the open/closed state of a Treeview item?
There was a tkinter option:
tkinter.wantObjects
that some people offered to change to False. It should make Tk to do not use TCL_objs. But when I tried it the TreeView looked broken.As a workaround I used BooleanVar in way like this:
This way seemed working to me