代码之家  ›  专栏  ›  技术社区  ›  Bill Bridge

如何取消填充Kivy Treeview?

  •  1
  • Bill Bridge  · 技术社区  · 8 年前

    考虑到kivy doc中的Treeview示例,我正在寻找一种取消填充Treeview的方法。但我找不到(我无法设计)一个清晰简洁的解决方案,该解决方案也适用于嵌套级别超过3级的TreeView(我的试验包括无法维护的if elif等决策树)。

    因此,以下示例的取消填充应将Treeview转换为新的树字典,结果是新的树字典与示例中的树完全相同:

    from kivy.app import App
    from kivy.uix.treeview import TreeViewLabel, TreeView
    from kivy.uix.floatlayout import FloatLayout
    
    
    def populate_tree_view(tree_view, parent, node):
        if parent is None:
            tree_node = tree_view.add_node(TreeViewLabel(text=node['node_id'],
                                                         is_open=True))
        else:
            tree_node = tree_view.add_node(TreeViewLabel(text=node['node_id'],
                                                         is_open=True), parent)
    
        for child_node in node['children']:
            populate_tree_view(tree_view, tree_node, child_node)
    
    
    tree = {'node_id': '1',
            'children': [{'node_id': '1.1',
                          'children': [{'node_id': '1.1.1',
                                        'children': [{'node_id': '1.1.1.1',
                                                      'children': []}]},
                                       {'node_id': '1.1.2',
                                        'children': []},
                                       {'node_id': '1.1.3',
                                        'children': []}]},
                          {'node_id': '1.2',
                           'children': []}]}
    # EDIT
    def treeToDict(node):
        if isinstance(node, TreeView):
            node = node.root
        if node.text == 'Tree One':
            node = node.nodes[0]
        d = dict()
        d['node_id'] = node.text
        d['children'] = []
        for child in node.nodes:
            d['children'].append(treeToDict(child))
        return d
    # EDIT END
    
    class TreeWidget(FloatLayout):
        def __init__(self, **kwargs):
            super(TreeWidget, self).__init__(**kwargs)
    
            tv = TreeView(root_options=dict(text='Tree One'),
                          hide_root=False,
                          indent_level=4)
    
            populate_tree_view(tv, None, tree)
    
            self.add_widget(tv)
    
            # EDIT
            print treeToDict(tv)
    
    
    class MyApp(App):
        def build(self):
            return TreeWidget()
    
    if __name__ == '__main__':
        MyApp().run()
    

    编辑 :

    对于depopulate,我的意思不是删除节点,而是转换字典中的树视图。原因如下。 我有一个内容编辑器来构建对象的树状视图。此对象结构需要以这样一种方式存储在数据库中,即使用populate\u tree\u view函数在编辑器中很容易再次复制。

    非常感谢您提前分享您的知识、时间和努力。

    1 回复  |  直到 8 年前
        1
  •  2
  •   John Anderson    8 年前

    不确定为什么减少树的数量应该相同,但这里有一个简单的减少树数量的方法:

    def depopulate(tv):
        iterator = tv.iterate_all_nodes()
        try:
            while True:
                node = iterator.next()
                tv.remove_node(node)
        except StopIteration:
            return
    

    这应该删除树中的所有节点,只留下根节点。

    要创建节点字典,应使用以下方法:

    def treeToDict(node):
        if isinstance(node, TreeView):
            node = node.root
        if node.text == 'Tree One':
            node = node.nodes[0]
        d = dict()
        d['node_id'] = node.text
        d['children'] = []
        for child in node.nodes:
            d['children'].append(treeToDict(child))
        return d
    

    首字母 if 此方法中的语句只是跳过 TreeView 小部件和根小部件(“树一”)。如果可以确保使用顶级节点调用此方法( node_id == 1 ),然后可以删除这些 如果 声明。该方法返回dict。