如何过滤Python中的ttk.treeview?
How to filter a ttk.treeview in Python?
我有一个 python tkinter
应用程序,其中包含一个 ttk.treeview
小部件。
小部件显示在具有特定扩展名的特定目录树上找到的文件列表 - 使用 tt.treeview
小部件构建起来很简单。
有一个启用树的 "on-the-fly" 过滤的请求 - 例如,用户输入 Entry
一些字符串,并且作为 he/she 类型,树删除元素到目前为止不匹配输入的字符串。
我正在浏览 Treeview
文档,尝试了 detach
和 reattach
方法,但没有成功。
detach
确实从树中删除了不匹配的元素,但是如果用户点击 Backspace,我将无法再正确地在树上迭代以恢复那些作为 get_children
方法的分离元素不会 return 它们。
def filter_tree(self):
search_by = self.search_entry.get()
self.tree_detach_leaf_by_regex(self.current_loaded_folder, search_by, "")
def tree_detach_leaf_by_regex(self, root, regex, parent):
if self.treeview.get_children(root):
for child in self.treeview.get_children(root):
self.tree_detach_leaf_by_regex(child, regex, root)
else:
if not re.match(regex, self.treeview.item(root)["text"]):
self.elements_index_within_parent[root] = self.treeview.index(root)
self.elements_parents[parent] = 1
self.treeview.detach(root)
else:
self.treeview.reattach(root, parent, self.elements_index_within_parent[root])
期待阅读您的建议。
为了让任何人都可以重复使用我的回答,除了直接回答您的问题之外,我还必须讲述更多内容。如果你直接想看我如何获取分离项(因此不使用无法获取分离项id的方法get_children
),请跳转到名称为_columns_searcher
的方法的定义。
简介
我们先定义一些属性。
@property
def _to_search(self):
key = 'to_search'
if key not in self._cache:
self._cache[key] = tk.StringVar()
return self._cache[key]
def _set_search_entry(self):
ent = ttk.Entry(
self.root, # or canvas, or frame ...
#...
textvariable=self._to_search
)
ent.grid(
#...
)
ent.bind(
'<Return>',
self._columns_searcher
)
return ent
@property
def search_entry(self):
key = 'search_entry'
if key not in self._cache:
self._cache[key] = self._set_search_entry()
return self._cache[key]
核心答案
接下来的部分直接展示了如何重新附加 用户分离的项目。首先请注意,正如 OP 所提到的,get_children
只有 return 附加项目的 ID。其次请注意,您唯一需要 重新附加 分离项目的是它们的 ID。因此,这意味着 trace/save 它们在分离时能够重新连接它们。
_detached = set()
def _columns_searcher(self, event):
# originally a set returns a tuple
children = list(self._detached) + list(self.tree.get_children())
self._detached = set()
query = self._to_search.get()
self._brut_searcher(children, query.lower())
请注意 上方的 children
包含所有项目,将它们分开。
def _brut_searcher(self, children, query):
i_r = -1
for item_id in children:
text = self.tree.item(item_id)['text'] # already contains the strin-concatenation (over columns) of the row's values
if query in text:
i_r += 1
self.tree.reattach(item_id, '', i_r)
else:
self._detached.add(item_id)
self.tree.detach(item_id)
据我所知,分离与删除几乎相同。
行不见了,您无权访问它。
如果您有高级树视图结构,则必须复制“分离的”项目,只是 id、名称或更多,然后遍历两个列表中的元素并将其排序。
不同之处在于,如果您分离项目并使用“存在”功能检查它的 ID,它应该 return true
我有一个 python tkinter
应用程序,其中包含一个 ttk.treeview
小部件。
小部件显示在具有特定扩展名的特定目录树上找到的文件列表 - 使用 tt.treeview
小部件构建起来很简单。
有一个启用树的 "on-the-fly" 过滤的请求 - 例如,用户输入 Entry
一些字符串,并且作为 he/she 类型,树删除元素到目前为止不匹配输入的字符串。
我正在浏览 Treeview
文档,尝试了 detach
和 reattach
方法,但没有成功。
detach
确实从树中删除了不匹配的元素,但是如果用户点击 Backspace,我将无法再正确地在树上迭代以恢复那些作为 get_children
方法的分离元素不会 return 它们。
def filter_tree(self):
search_by = self.search_entry.get()
self.tree_detach_leaf_by_regex(self.current_loaded_folder, search_by, "")
def tree_detach_leaf_by_regex(self, root, regex, parent):
if self.treeview.get_children(root):
for child in self.treeview.get_children(root):
self.tree_detach_leaf_by_regex(child, regex, root)
else:
if not re.match(regex, self.treeview.item(root)["text"]):
self.elements_index_within_parent[root] = self.treeview.index(root)
self.elements_parents[parent] = 1
self.treeview.detach(root)
else:
self.treeview.reattach(root, parent, self.elements_index_within_parent[root])
期待阅读您的建议。
为了让任何人都可以重复使用我的回答,除了直接回答您的问题之外,我还必须讲述更多内容。如果你直接想看我如何获取分离项(因此不使用无法获取分离项id的方法get_children
),请跳转到名称为_columns_searcher
的方法的定义。
简介
我们先定义一些属性。
@property
def _to_search(self):
key = 'to_search'
if key not in self._cache:
self._cache[key] = tk.StringVar()
return self._cache[key]
def _set_search_entry(self):
ent = ttk.Entry(
self.root, # or canvas, or frame ...
#...
textvariable=self._to_search
)
ent.grid(
#...
)
ent.bind(
'<Return>',
self._columns_searcher
)
return ent
@property
def search_entry(self):
key = 'search_entry'
if key not in self._cache:
self._cache[key] = self._set_search_entry()
return self._cache[key]
核心答案
接下来的部分直接展示了如何重新附加 用户分离的项目。首先请注意,正如 OP 所提到的,get_children
只有 return 附加项目的 ID。其次请注意,您唯一需要 重新附加 分离项目的是它们的 ID。因此,这意味着 trace/save 它们在分离时能够重新连接它们。
_detached = set()
def _columns_searcher(self, event):
# originally a set returns a tuple
children = list(self._detached) + list(self.tree.get_children())
self._detached = set()
query = self._to_search.get()
self._brut_searcher(children, query.lower())
请注意 上方的 children
包含所有项目,将它们分开。
def _brut_searcher(self, children, query):
i_r = -1
for item_id in children:
text = self.tree.item(item_id)['text'] # already contains the strin-concatenation (over columns) of the row's values
if query in text:
i_r += 1
self.tree.reattach(item_id, '', i_r)
else:
self._detached.add(item_id)
self.tree.detach(item_id)
据我所知,分离与删除几乎相同。 行不见了,您无权访问它。 如果您有高级树视图结构,则必须复制“分离的”项目,只是 id、名称或更多,然后遍历两个列表中的元素并将其排序。 不同之处在于,如果您分离项目并使用“存在”功能检查它的 ID,它应该 return true