Python / kivy: передать текст textinput из одного класса в другой класс

Когда я запускаю test.py, то показывает name TextInput. Когда я печатаю в TextInput, затем показывает Tree View с filter TextInput. Когда я печатаю что-то в filter TextInput, он показывает результат в соответствии с типом keyword.
Но я хочу, чтобы когда кто-то вводил name TextInput, затем вводил keyword, вставленный в filter TextInput, и результат должен был отображаться в соответствии с проходом keyword.

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 = (500, 400)


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)



class TreeViewLabel(Label, TreeViewNode):
    pass


class TreeviewGroup(Popup):
    treeview = ObjectProperty(None)
    tv = ObjectProperty(None)
    popup = ObjectProperty()

    def __init__(self,obj, **kwargs):
        super(TreeviewGroup, self).__init__(**kwargs)
        self.tv = TreeView(root_options=dict(text=""),
                       hide_root=False,
                       indent_level=4)

        rows = [('test{}').format(i) for i in range(1, 20)]

        tree = [{'node_id': r, 'children': []} for r in rows]

        self.tv.bind(minimum_height=self.treeview.setter('height'))
        for branch in tree:
            populate_tree_view(self.tv, None, branch)
        self.treeview.add_widget(self.tv)

    def filter(self, f):
        #self.ti.text = "text12"
        self.treeview.clear_widgets()
        self.tv = TreeView(root_options=dict(text=""),
                           hide_root=False,
                           indent_level=4)

        rows = [('test{}').format(i) for i in range(1, 20)]

        tree = []

        for r in rows:
            tree.append({'node_id': r, 'children': []})
        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 remove_widgets(self):
        for child in [child for child in self.treeview.children]:
            self.treeview.remove_widget(child)


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

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


class Group(App):
    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.name.text = self.text
        app.root.popup.dismiss()

<TreeviewGroup>:
    treeview: treeview
    title: "Select"
    title_size: 17
    size: 800, 800
    auto_dismiss: False
    scroll: scroll
    fltr : fltr

    BoxLayout
        orientation: "vertical"
        TextInput:
            id : fltr
            size_hint_y: .13
            on_text: root.filter(self.text)

        ScrollView:
            id: scroll
            size_hint: 1, .9


            BoxLayout:
                size_hint_y: None
                id: treeview

        GridLayout:
            cols: 2
            row_default_height: '20dp'
            size_hint: .5, 0.1
            pos_hint: {'x': .25, 'y': 1}
            Button:
                text: 'Ok'
                on_release: root.dismiss()

            Button:
                text: 'Cancel'
                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:
    name: name

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

        CustomLabel:
            text: ' '

        CustomLabel:
            text: ' '

        CustomLabel:
            text: 'Name'

        SingleLineTextInput:
            id: name
            text:' '
            multiline: False
            on_text: root.display_groups(self)



        GreenButton:
            text: 'Ok'

        GreenButton:
            text: 'Cancel'
            on_press: app.stop()
0
0
560
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Чтобы передать слово целиком, например ключевое слово или 0, замените on_text на on_text_validate.

СУХОЙ - Не повторяйтесь

Есть повторяющиеся коды, я превратил их в модули для удобства обслуживания.

def create_treeview_root(self):
...
def create_treeview_branch(self, obj):
...
def dismiss_callback(self):

Фрагмент

GroupScreen:
    ...
        SingleLineTextInput:
            id: name
            focus: True
            multiline: False
            on_text_validate: root.display_groups(self)

Пример

main.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, StringProperty, ListProperty
Window.size = (500, 400)


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)


class TreeViewLabel(Label, TreeViewNode):
    pass


class TreeviewGroup(Popup):
    treeview = ObjectProperty(None)
    tv = ObjectProperty(None)
    filter_text = StringProperty('')
    tree = ListProperty([])

    def __init__(self, obj, **kwargs):
        super(TreeviewGroup, self).__init__(**kwargs)
        self.create_treeview_root()
        rows = [('test{}').format(i) for i in range(1, 20)]
        self.tree = [{'node_id': r, 'children': []} for r in rows]
        self.tv.bind(minimum_height=self.treeview.setter('height'))
        self.create_treeview_branch(self.tree)

    def create_treeview_root(self):
        self.tv = TreeView(root_options=dict(text=""),
                           hide_root=False,
                           indent_level=4)

    def create_treeview_branch(self, obj):
        for branch in obj:
            populate_tree_view(self.tv, None, branch)
        self.treeview.add_widget(self.tv)

    def on_open(self):
        self.filter_text = App.get_running_app().root.name.text

    def dismiss_callback(self):
        self.treeview.clear_widgets()
        self.dismiss()
        App.get_running_app().root.name.focus = True

    def filter(self, f):
        self.treeview.clear_widgets()
        self.create_treeview_root()
        new_tree = []
        for n in self.tree:
            if f.lower() in n['node_id'].lower():
                new_tree.append(n)
        self.create_treeview_branch(new_tree)


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

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


class Group(App):
    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.name.text = self.text
        app.root.popup.dismiss_callback()

<TreeviewGroup>:
    treeview: treeview
    title: "Select"
    title_size: 17
    size: 800, 800
    auto_dismiss: False
    scroll: scroll
    fltr : fltr

    BoxLayout
        orientation: "vertical"
        TextInput:
            id : fltr
            focus: True
            text: root.filter_text
            size_hint_y: .13
            on_text: root.filter(self.text)

        ScrollView:
            id: scroll
            size_hint: 1, .9


            BoxLayout:
                size_hint_y: None
                id: treeview

        GridLayout:
            cols: 2
            row_default_height: '20dp'
            size_hint: .5, 0.1
            pos_hint: {'x': .25, 'y': 1}
            Button:
                text: 'Ok'
                on_release:
                    root.dismiss_callback()

            Button:
                text: 'Cancel'
                on_release:
                    root.dismiss_callback()

<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:
    name: name

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

        CustomLabel:
            text: ' '

        CustomLabel:
            text: ' '

        CustomLabel:
            text: 'Name'

        SingleLineTextInput:
            id: name
            focus: True
            multiline: False
            on_text_validate: root.display_groups(self)

        GreenButton:
            text: 'Ok'

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

Выход

Img01 - App StartupImg02 - Typed keywordImg03 - keyword at Filter after pressed ENTERImg04 - Typed 0 (zero)Img05 - 0 (zero) at Filter after pressed ENTER

Другие вопросы по теме