如何在 Python 中过滤 ttk.treeview? [英] How to filter a ttk.treeview in Python?

查看:34
本文介绍了如何在 Python 中过滤 ttk.treeview?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个包含 ttk.treeview 小部件的 python tkinter 应用程序.

I have a python tkinter application that contains a ttk.treeview widget.

小部件显示在具有特定扩展名的特定目录树上找到的文件列表 - 使用 tt.treeview 小部件构建这很简单.

The widget displays a list of files found on a specific directory tree with a specific extension - this was trivial to build with tt.treeview widget.

有一个请求启用即时"过滤树 - 例如,用户在 Entry 中输入一些字符串,当他/她输入时,树会删除元素到目前为止与输入的字符串不匹配.

There is a request to enable "on-the-fly" filtering of the tree - e.g., the user types in an Entry some string, and as he/she types, the tree removes elements that don't match the typed string so far.

我正在浏览 Treeview 文档,尝试了 detachreattach 方法,但没有成功.

I was exploring the Treeview documentation, tried the detach and reattach methods but with no luck.

detach 确实从树中删除了不匹配的元素,但是如果用户点击 Backspace,我就不能再在树上正确迭代以恢复那些分离的元素因为 get_children 方法不会返回它们.

detach indeed removes the non-matched elements from the tree, but if the user hit Backspace, I can no longer iterate correctly on the tree to restore those detached elements as get_children method will not return them.

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 的方法的定义.

To make my answer reusable by anybody, I have to tell more than directly answering your question. If you directly want to see how I do to get detached items (thus without using the method get_children which cannot get detached items' id), jump to the definition of the method whose name is _columns_searcher.

<小时>简介

让我们先定义一些属性.

Let's first define some attributes.

@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 仅返回附加项目的 id.第二个注意事项,您唯一需要重新附加分离的项目是它们的 id.这意味着在它们分离时跟踪/保存它们以便能够重新连接它们.

What follows is the part which directly show how to re-attach user-detached items. First note that, as the OP mentions, get_children only return ids of attached items. Second note that the only thing you need to re-attach detached items is their id. Which implies thus to trace/save them when they are detached so as to be able to re-attach them.

_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包含所有项目,将它们分开.

Note that children above contains all items, be them detached.

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)

这篇关于如何在 Python 中过滤 ttk.treeview?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆