触发回调时,tkinter-treeview打开状态不是最新的



我目前正在开发一个tkinter应用程序,该应用程序使用树视图元素在层次结构中显示数据。在这个应用程序的一部分中,我需要更新项目的数据。不幸的是,获取这些数据(在时间和处理方面(非常昂贵,所以我现在只更新当前可见的项目。

我遇到的问题是,当我将一个(左键单击(事件绑定到一个项目,然后在树视图中查询打开的项目以尝试确定什么是可见的时,会返回以前打开的项目,但当前打开的项目不会(直到单击下一个项目(。

我看到了这个关于查询(和设置(打开状态的问题,但它似乎不能满足我的需求。

我有以下简化的代码,它演示了这个问题:

## import required libraries
import tkinter
import tkinter.ttk
import random
import string
## event handler for when items are left clicked
def item_clicked(event):        
tree = event.widget

## we assume event.widget is the treeview    
current_item = tree.item(tree.identify('item', event.x, event.y))
print('Clicked ' + str(current_item['text']))

## for each itewm in the treeview
for element in tree.get_children():    
## if it has elements under it..
if len(tree.get_children(element)) > 0:
## get the element name
element_name = tree.item(element)['text']
## check if it is open
if tree.item(element)['open'] is True:
print('Parent ' + element_name + ' is open')
else:
print('Parent ' + element_name + ' is closed')

## make the window and treeview
root = tkinter.Tk()
root.title('Treeview test')
tree = tkinter.ttk.Treeview(root, selectmode = 'browse', columns = ('num', 'let'))
tree.heading('#0', text = 'Name')
tree.heading('num', text = 'Numbers')
tree.heading('let', text = 'Letters')
tree.bind('<Button-1>', item_clicked)
tree.pack()
## populate the treeview with psuedo-random data
parents = ['']
for i in range(100):
id = str(i)
## higher probability that this won't be under anything
if random.randrange(50) > 40:
parent = random.choice(parents)
else:
parent = ''

## make up some data
tree.insert(parent, 'end', iid = id, text = 'Item ' + id)
tree.set(id, 'num', ''.join(random.choices(string.digits, k=10)))
tree.set(id, 'let', ''.join(random.choices(string.ascii_uppercase, k=10)))

parents.append(id)
## main event loop (blocking)    
root.mainloop()

此代码将生成一个树视图,其中包含随机继承的100个项目。单击任何项目都将打印一个有子项目且当前已展开(打开(的项目列表。问题是,与我的主代码一样,没有报告最新打开的项目(即落后一步(。

在查询树视图的状态之前(在item_clicked函数的开头(向树视图添加update((并不能解决这个问题。

  • 如何在上面代码的事件处理程序中准确地获得项目的打开状态
  • 事件在项目实际展开(打开(之前被激发是问题吗?如果是,为什么update((没有解决这个问题
  • 树视图小部件是否存在返回当前可见项目列表的替代函数

使用Python 3.7.3(Tk版本8.6.9(在Windows 10上运行。

在上面的代码中将事件绑定从<Button-1>更改为<ButtonRelease-1>解决了这个问题。

需要注意的是,在上面的代码中,打开/关闭状态只会为具有没有父级的子级的项目打印(即,它不会下降到树中(。要解决此问题,只需递归地对每个具有子项的项调用tree.get_children(item_id)

最新更新