kivy / python:在树视图中选择节点时绑定事件

时间:2017-11-13 11:35:30

标签: python python-2.7 kivy kivy-language

test.py

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



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 = []
rows = [(1, 'test1', 11), (2, 'test2', 2), (3, 'test3', 3), (4, 'test4', 4), (5, 'test5', 1)]
for r in rows:
    tree.append({'node_id': r[1], 'children': []})



class TreeViewLabel(Label, TreeViewNode):
    pass


class TreeviewGroup(Popup):
    treeview = ObjectProperty(None)
    tv = ObjectProperty(None)
    #ti = ObjectProperty()

    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 select_node(self, node):
        '''Select a node in the tree.
                '''
        if node.no_selection:
            return
        if self._selected_node:
            self._selected_node.is_selected = False
        node.is_selected = True
        self._selected_node = node
        print(node)

class GroupScreen(Screen):
    groupName = ObjectProperty(None)
    popup = ObjectProperty(None)

    def display_groups(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.
                '''
        if node.no_selection:
            return
        if self._selected_node:
            self._selected_node.is_selected = False
        node.is_selected = True
        self._selected_node = node
        print(node)


class Group(App):

    #rows = [(1, 'test1', 111), (2, 'test2', 112), (3, 'test3', 113), (4, 'test4', 114)]
    def build(self):
        self.root = Builder.load_file('test.kv')
        return self.root


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

test.kv

#:kivy 1.10.0

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

<TreeviewGroup>:
    id: treeview
    treeview: treeview
    title: "Select City"
    size_hint: None, None
    size: 400, 400
    auto_dismiss: False

    BoxLayout
        orientation: "vertical"
        #TextInput:
            #id: ti
            #size_hint_y: .1
            #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

GroupScreen:
    stateName: stateName

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

        CustomLabel:
            text: 'Name'

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

        CustomLabel:
            text: 'Code'

        CustomLabel:
            text: '08'


        GreenButton:
            text: 'Ok'
            #on_press: root.insert_data(stateName.text, cityName.text, shortName.text , pinCode.text)


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

        Label:

        Label:

当我在州名中键入任何内容时,弹出一个带有树视图结构的弹出窗口。

我想要点击任何节点然后从数据库中检索状态代码。并将状态代码放在前面。这次'08'是静态值。数据库查询对我来说没问题,但我不知道如何在将值放在状态代码前面后传入一个.py文件。弹出应该关闭。

1 个答案:

答案 0 :(得分:2)

您可以通过向表示状态代码的Groupscreen类添加字符串属性属性来执行此操作,然后编辑select_node方法以触发更改

...
from kivy.properties import ObjectProperty, StringProperty

...

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

...

    def select_node(self, node):
        '''Select a node in the tree.
            '''
        for r in rows:
            if node.text == r[1]:
                self.statecode = str(r[2])
                break

然后在kv:

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

...

GroupScreen:
    stateName: stateName

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

        CustomLabel:
            text: 'State Name'

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

        CustomLabel:
            text: 'State Code'

        CustomLabel:
            text: root.statecode

...