在kivy中使用多个treeview小部件

问题描述 投票:0回答:1

test.py

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
import sys
Window.clearcolor = (.152, .149, .149, 0)
Window.size = (700, 330)


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)

rows = [('1','1','city1'),('2','2','city2'),('3','3','city3')]
tree = []

for r in rows:
    tree.append({'node_id': r[2], '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 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)

def populate_tree_view_area(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)

rows = [('1','1','area1'),('2','2','area2'),('3','3','area3')]
treeArea = []

for r in rows:
    treeArea.append({'node_id': r[2], 'children': []})

class TreeviewArea(Popup):
    treeviewArea = ObjectProperty(None)
    tv = ObjectProperty(None)
    #ti = ObjectProperty()

    def __init__(self, **kwargs):
        super(TreeviewArea, self).__init__(**kwargs)
        self.tv = TreeView(root_options=dict(text=""),
                       hide_root=False,
                       indent_level=4)
        for branch in treeArea:
            populate_tree_view_area(self.tv, None, branch)
        self.remove_widgets()
        self.treeviewArea.add_widget(self.tv)

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

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

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

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


class FactArea(App):
    def build(self):
        self.root = Builder.load_file('test.kv')
        return self.root



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

test.kv

:kivy 1.10.0

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

<TreeviewGroup>:
    id: treeview
    treeview: treeview
    title: "Select City"
    size_hint: None, None
    size: 400, 350
    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()

<TreeviewGroupArea>:
    id: treeviewArea
    treeviewArea: treeviewArea
    title: "Select City"
    size_hint: None, None
    size: 400, 350
    auto_dismiss: False

    BoxLayout
        orientation: "vertical"
        #TextInput:
            #id: ti
            #size_hint_y: .1
            #on_text: root.filter(self.text)
        BoxLayout:
            id: treeviewArea
            #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.200

AreaScreen:
    cityName: cityName

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

        Label:
            text: 'City'
            text_size: self.size
            valign: 'middle'
            padding_x: 50


        SingleLineTextInput:
            id: cityName
            font_size_valign:self.height*0.4
            on_text: root.display_cities(self)

        Label:
            text: 'Area'
            text_size: self.size
            valign: 'middle'
            padding_x: 50


        SingleLineTextInput:
            id: areaName
            on_text: root.display_areas(self)


        GreenButton:
            text: 'Ok'
            on_press: root.insert_data(cityName.text, areaName.text)



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

如果我在城市中输入任何内容然后城市显示在树视图中。但是我在区域中键入任何内容然后还显示city.I已经为区域编写了单独的功能但我不知道出了什么问题?如果有可能使用相同的功能if if else城市树视图和区域树视图的条件。代码不会重复,所以它会更好。

我选择城市然后将值放入城市TextBox但我选择区域然后值也设置在城市TextBox中。如何将值放在单独的TextBox中?城市treeView值放在城市TextBox和Area TreeView值放在区域TextBox中。

python python-2.7 kivy kivy-language
1个回答
1
投票

我知道你试图修改但是还不够,你必须为每个弹出窗口重新定义TreeView类和TreeViewLabel

我只会发布区域弹出窗口所需的内容

...
def populate_tree_view_area(tree_view, parent, node):
    if parent is None:
        tree_node = tree_view.add_node(TreeViewLabelArea(text=node['node_id'],
                                                 is_open=True))
    else:
        tree_node = tree_view.add_node(TreeViewLabelArea(text=node['node_id'],
                                                 is_open=True), parent)

    for child_node in node['children']:
        populate_tree_view(tree_view, tree_node, child_node)

rowsa = [('1','1','area1'),('2','2','area2'),('3','3','area3')]
treeArea = []

for r in rowsa:
    treeArea.append({'node_id': r[2], 'children': []}) 

class TreeViewLabelArea(Label, TreeViewNode):
    pass

class TreeviewArea(Popup):
#You can let it as it is

...

class AreaScreen(Screen):
    groupName = ObjectProperty(None)
    popupcity = ObjectProperty(None)
    popuparea = ObjectProperty(None)
    #statecode = StringProperty('')

    ...

    def display_areas(self, instance):
        if len(instance.text) > 0:
            if self.popuparea is None:
                self.popuparea = TreeviewArea()
            #self.popup.filter(instance.text)
            self.popuparea.open()

然后在你的kv中用TreeViewArea替换TreaviewGroupArea,如main中所定义,并添加TreeViewLabelArea规则

...
<TreeViewLabelArea>:
    height: 24
    on_touch_down:
        app.root.areaName.text = self.text
        #app.root.select_node(self)
        app.root.popuparea.dismiss()

最后在AreaScreen规则中添加areaName属性

...
AreaScreen:
    cityName: cityName
    areaName: areaName
...

我希望这有帮助

© www.soinside.com 2019 - 2024. All rights reserved.