質問

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:

  1. Inconsistency: while initialized to ints, later the values assigned are _tkinter objects
  2. 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?

役に立ちましたか?

解決 2

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:

open_opt = BooleanVar()
for row in tree.get_children():
    open_opt.set(str(tree.item(row, option='open')))
    opened = open_opt.get()

This way seemed working to me

他のヒント

In the Lynda course by Barron Stone, Python GUI Development with Tkinter, a lesson video, Building a hierarchical treeview, has an example that shows how to get an "is open?" result. I have modified the example below:

Python 3.5 in IDLE console

>>> from tkinter import *
>>> from tkinter import ttk
>>> root = Tk()
>>> treeview = ttk.Treeview(root)
>>> treeview.pack()
>>> treeview.insert('', '0', 'par1', text = 'Parent')
'par1'
>>> treeview.insert('par1', '0', 'child1', text = 'Child')
'child1'
>>> treeview.item('par1', 'open')
0
>>> treeview.item('par1', open = True)
{}
>>> treeview.item('par1', 'open')
1
>>>

Not a boolean as requested, but an int that is just as good.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top