【发布时间】:2021-09-30 06:58:28
【问题描述】:
我目前正在开发一个 tkinter 应用程序,该应用程序使用树视图元素在层次结构中显示数据。在此应用程序的一部分中,我需要更新项目的数据。不幸的是,获取这些数据很昂贵(时间和处理上),所以我现在只更新当前可见的项目。
我遇到的问题是,当我将(左键单击)事件绑定到一个项目,然后在树视图中查询打开的项目以尝试确定可见的内容时,会返回以前打开的项目,但当前打开的项目是不是(直到单击后续项目)。
我看到this question关于查询(和设置)打开状态,但它似乎不能满足我的需求。
我有以下简化的代码,它演示了这个问题:
## 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() 不能解决此问题?
- 是否存在可供树视图小部件返回当前可见项目列表的替代函数?
在 Windows 10 上运行 Python 3.7.3(Tk 版本 8.6.9)。
【问题讨论】:
-
您是否尝试绑定到
<<TreeviewOpen>>和/或<<TreeviewSelect>>? -
绑定
<ButtonRelease-1>或<<TreevewSelect>>而不是<Button-1>(与<ButtonPress-1>相同)。 -
> 和
都解决了跟踪打开状态的问题,但只有后者似乎将树视图传递给 event.widget