首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在子节点中应用搜索

如何在子节点中应用搜索
EN

Stack Overflow用户
提问于 2017-11-16 06:41:24
回答 1查看 199关注 0票数 1

demo.py

代码语言:javascript
复制
import sqlite3 as lite

from kivy.uix.screenmanager import Screen
from kivy.app import App
from kivy.lang import Builder
from kivy.core.window import Window
from kivy.uix.popup import Popup
from kivy.uix.treeview import TreeView, TreeViewLabel, TreeViewNode
from kivy.uix.label import Label
from kivy.properties import ObjectProperty,StringProperty

Window.size = (700, 530)


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 = []

tree = [{'node_id': 'Capital Account',
         'children': [{'node_id': 'Reserves & Surplus',
                       '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': []}]},
        {'node_id': 'Current Assests',
         'children': []}]


class TreeViewLabel(Label, TreeViewNode):
    pass

class TestViewLabel():
    pass


class TreeviewGroup(Popup):
    treeview = ObjectProperty(None)
    tv = ObjectProperty(None)
    ti = ObjectProperty()
    abc = StringProperty('c')

    def __init__(self, **kwargs):
        super(TreeviewGroup, self).__init__(**kwargs)
        self.tv = TreeView(root_options=dict(text=""),
                       hide_root=False,
                       indent_level=4)
        for branch in tree:
            populate_tree_view(self.tv, None, branch)
        self.remove_widgets()
        self.treeview.add_widget(self.tv)

    def remove_widgets(self):
        for child in [child for child in self.treeview.children]:
            self.treeview.remove_widget(child)

    def filter(self, f):
        self.treeview.clear_widgets()
        self.tv = TreeView(root_options=dict(text=""),
                           hide_root=False,
                           indent_level=4)
        new_tree = []
        for n in tree:
            if f.lower() in n['node_id'].lower():
                new_tree.append(n)
        for branch in new_tree:
            populate_tree_view(self.tv, None, branch)

        self.treeview.add_widget(self.tv)



class CityScreen(Screen):
    groupName = ObjectProperty(None)
    popup = ObjectProperty(None)
    statecode = StringProperty('')

    def display_states(self, instance):
        if len(instance.text) > 0:
            if self.popup is None:
                self.popup = TreeviewGroup()
            self.popup.filter(instance.text)
            self.popup.open()

    def select_node(self, node):
        '''Select a node in the tree.
            '''

class MyApp(App):

    def build(self):
        self.root = Builder.load_file('demo.kv')
        return self.root


if __name__ == '__main__':
    MyApp().run()

demo.kv

代码语言:javascript
复制
#:kivy 1.10.0

<TreeViewLabel>:
    on_touch_down:
        app.root.stateName.text = self.text
        app.root.select_node(self)
        app.root.popup.dismiss()

<TestViewLabel>:
    on_touch_down:
        app.root.stateName.text = self.text
        app.root.select_node(self)
        app.root.popup.dismiss()

<TreeviewGroup>:
    id: treeview
    treeview: treeview
    size_hint: None, None
    size: 400, 400
    auto_dismiss: False

    BoxLayout
        orientation: "vertical"
        TextInput:
            id: ti
            size_hint_y: .1
            text: root.abc
            on_text: root.filter(self.text)
        BoxLayout:
            id: treeview
            #on_press: root.select_node(self.text)
        Button:
            size_hint: 1, 0.1
            text: "Close"
            on_release: root.dismiss()


<CustomLabel@Label>:
    text_size: self.size
    valign: "middle"
    padding_x: 5

<SingleLineTextInput@TextInput>:
    multiline: False

<GreenButton@Button>:
    background_color: 1, 1, 1, 1
    size_hint_y: None
    height: self.parent.height * 0.150

CityScreen:
    stateName: stateName

    GridLayout:
        cols: 2
        padding : 30,30
        spacing: 10, 10
        row_default_height: '40dp'

        CustomLabel:
            text: 'Text'

        SingleLineTextInput:
            id: stateName
            on_text: root.display_states(self)

        #Spinner:
            #text: "State Code"
            #values: ["111", "112", "113", "114"]
            #values: app.r
            #background_color: color_button if self.state == 'normal' else color_button_pressed
            #background_down: 'atlas://data/images/defaulttheme/spinner'
            #color: color_font
            #option_cls: Factory.get("MySpinnerOption")
            #size_hint: None, None

        GreenButton:
            text: 'Ok'
            on_press: root.insert_data(stateName.text)


        GreenButton:
            text: 'Cancel'
            on_press: app.stop()

        Label:

        Label:
  1. 当我在文本TextBox中输入某项内容时,弹出的内容将是show.Then,如何将值从文本TextBox传递到弹出的搜索框中。
  2. SearchBox为父节点工作得很好,不是为孩子工作,node.How能工作吗?
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-11-17 12:37:47

  1. 当我在文本TextBox中键入一些内容时,弹出的内容将是show.Then,如何将值从文本TextBox传递到弹出框中,就像附加的图像一样。

由于在打开文本输入属性时,弹出窗口中有文本输入属性,所以可以传递文本:

代码语言:javascript
复制
...
<TreeviewGroup>:
    id: treeview
    treeview: treeview
    size_hint: None, None
    size: 400, 400
    auto_dismiss: False
    ti: ti
    BoxLayout
        orientation: "vertical"
        TextInput:
            id: ti
            size_hint_y: .1
            on_text: root.filter(self.text)

然后在.py中:

代码语言:javascript
复制
...

class CityScreen(Screen):
    groupName = ObjectProperty(None)
    popup = ObjectProperty(None)
    statecode = StringProperty('')

    def display_states(self, instance):
        if len(instance.text) > 0:
            if self.popup is None:
                self.popup = TreeviewGroup()
            self.popup.ti.text = instance.text
            self.popup.filter(instance.text)
            self.popup.open()
...

2 SearchBox非常适合家长节点,不是为孩子工作的,node.How会工作吗?

这不是一件容易的事,这个问题值得赏赐。

若要在treeView具有也是父级的子级时创建一个筛选器,则需要执行许多递归操作

首先,将这些函数添加到.py中

代码语言:javascript
复制
...
def get_children(n):
    '''get all the children in the node whithout her children'''
    if len(n['children']) == 0:
        return []
    else:
        children = [e['node_id'] for e in n['children']]
        for child in n['children']:
            children.extend([c for c in get_children(child)])
        return children


def get_children2(n, t):
    '''get the node with n as id'''
    if t is []:
        return False
    else:
        for child in t:
            if child['node_id'] == n:
                return child
            else:
                r = get_children2(n, child['children'])
                if r:
                    return r

def roots(n):
    '''return the roots (if a node have child it is a root)'''
    if len(n['children']) == 0:
        return [None]
    else:
        l = [n['node_id']]
        for c in n['children']:
            l.extend(roots(c))
        return l


def get_roots(t):
    '''this one is just to remove the None from the result of the first one'''
    fl = []
    for n in t:
        l = roots(n)
        li = []
        for e in l:
            if e is not None:
                li.append(e)
        fl.extend(li)
        if len(n['children']) == 0:
            fl.append(n['node_id'])
    return fl

...

现在您可以更改TreeView的筛选方法:

代码语言:javascript
复制
...
class TreeviewGroup(Popup):
    treeview = ObjectProperty(None)
    tv = ObjectProperty(None)
    ti = ObjectProperty()

    ...

    def filter(self, f):
        self.tv = TreeView(root_options=dict(text=""),
                           hide_root=False,
                           indent_level=4)
        for branch in tree:
            populate_tree_view(self.tv, None, branch)
        self.remove_widgets()
        self.treeview.add_widget(self.tv)
        l = []
        l_roots = get_roots(tree)
        dict_roots = []
        for node in self.tv.iterate_all_nodes():
            l.append(node)
        for i in range(len(l)):
            if l[i].text in l_roots:
                dict_roots.append({'ind': i, 'id': l[i].text})
        roots_childs = {}
        for e in l:
            try:
                nod = get_children2(e.text, tree)
                roots_childs[e.text] = get_children(nod)
            except TypeError:
                pass
        to_remove = []            
        for e in roots_childs:
            for child in roots_childs[e]:
                if child not in l_roots:
                    if f.lower() not in child.lower():
                        if child not in to_remove:
                            to_remove.append(child)
            n = 0
            for child in roots_childs[e]:
                if child in to_remove:
                    n += 1
            if n == len(roots_childs[e]):
                if f.lower() not in e.lower():
                    to_remove.append(e)
        for n in l:
            if n.text in to_remove:
                self.tv.remove_node(n)

更新我忘了在kv中的TreeViewGroop中添加ti --现在已经修复了

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47323210

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档