Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/ant/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Kivy:无法更新其他类的文本输入值_Python_Kivy_Textinput - Fatal编程技术网

Python Kivy:无法更新其他类的文本输入值

Python Kivy:无法更新其他类的文本输入值,python,kivy,textinput,Python,Kivy,Textinput,我是kivy的新手。我正在尝试将文本输入值更改为显示在另一个类的文本输入框中的字符串值,但没有传递任何内容 我在MyFirstScreen类中有以下小部件: 一个包含多个项目的RecycleView每个项目都是一个字典 两个文本输入 我想做的是:当选择RecycleView中的每个项目时,TextInputs应该更新并加载所选项目字典的相应值 但当我尝试从另一个类SelectableLabel访问当前TextInput的值时: 以及我的.kv代码: 问题是因为在update_text_输入中使用

我是kivy的新手。我正在尝试将文本输入值更改为显示在另一个类的文本输入框中的字符串值,但没有传递任何内容

我在MyFirstScreen类中有以下小部件:

一个包含多个项目的RecycleView每个项目都是一个字典 两个文本输入 我想做的是:当选择RecycleView中的每个项目时,TextInputs应该更新并加载所选项目字典的相应值

但当我尝试从另一个类SelectableLabel访问当前TextInput的值时:

以及我的.kv代码:

问题是因为在update_text_输入中使用MyFirstScreen会创建类MyFirstScreen的新实例,但必须使用现有实例

这应该是更好的方法,但在这一刻,我唯一的想法是使用家长为这一点

因为这些元素之间有许多小部件,所以它需要许多父元素:

我使用printself.parent、next printself.parent.parent等找到了它


可能使用MyFirstScreen创建类MyFirstScreen的第二个实例,并从第二个实例读取文本,而不是访问原始的第一个实例。当您再次运行update_text_输入时,您将创建MyFirstScreen类的第三个、第四个、第五个等实例,而不是使用第一个实例。但只有第一个实例可能有文本,您可以在文本输入中输入。顺便说一句:如果您将系统名称文本输入id:system名称文本输入id移动到RecycleViewWidget:则您将需要更少的家长。亲爱的furas,再次感谢您的帮助。这个问题已经解决了,但我发现了你建议的解决方案的新问题。这种情况下有一个错误:1.如果我选择了一个项目,例如:用户1->TextInputs值加载正确。2.然后向下滚动,直到所选项目完全隐藏在RecycleView中。3.我向上滚动以再次显示所选项目。当我想执行第3步时,立即出现了这个错误:my_text_input=self.parent.parent.parent.parent.parent.system_name_text_input_id AttributeError:“NoneType”对象没有属性“parent”有什么问题吗?我必须运行代码才能理解这个问题。在新页面上创建新问题-您将有更多的空间来放置完整的代码、完整的错误消息和描述问题。新的人会看到它-所以也许有人会找到更好的解决方案。我的代码没有变化。刚刚发生了新的错误。但是,如果需要创建新问题,我会这样做。以下是我的新问题:
class SelectableLabel(RecycleDataViewBehavior, Label):
    #...
    def update_text_inputs(self, *kwarg):
        my_text_input = MyFirstScreen().ids.system_name_text_input_id #<--i can access to widget
        print("my_print_val is:", my_text_input.text) #<--but widget's current text value is : ''
        my_text_input.text = "Updated Value"
from kivy.app import App
from kivy.lang import Builder
from kivy.properties import ObjectProperty
from kivy.uix.label import Label
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.recycleview import RecycleView
from kivy.uix.recycleview.views import RecycleDataViewBehavior
from kivy.properties import BooleanProperty
from kivy.uix.recycleboxlayout import RecycleBoxLayout
from kivy.uix.behaviors import FocusBehavior
from kivy.uix.recycleview.layout import LayoutSelectionBehavior


class Manager(ScreenManager):

    def __init__(self, **kwargs):
        super().__init__(**kwargs)


class MyFirstScreen(Screen):
    system_name_text_input_id = ObjectProperty(None)

    def __init__(self, **kwarg):
        super().__init__(**kwarg)
        print("__init__ of MyFirstScreen is Called")

    def get_text_inputs(self):
        ret_val = self.ids.system_name_text_input_id.text
        print("get_text_input is called, ret_val:", ret_val)
        return ret_val


class RecycleViewWidget(RecycleView):
    def __init__(self, **kwargs):
        super(RecycleViewWidget, self).__init__(**kwargs)
        self.items_of_rv = []
        for i in range(1, 21):
            self.items_of_rv.append(
                {"color": (0, 0, 0, 1), "font_size": "20", "text": f"User {i}",
                 "user_id": f"{100 * i}"})
        self.data = [item for item in self.items_of_rv]


class SelectableRecycleBoxLayout(FocusBehavior, LayoutSelectionBehavior, RecycleBoxLayout):
    """ Adds selection and focus behaviour to the view. """


class SelectableLabel(RecycleDataViewBehavior, Label):
    """ Add selection support to the Label """
    index = None
    selected = BooleanProperty(False)
    selectable = BooleanProperty(True)

    def refresh_view_attrs(self, rv, index, data):
        """ Catch and handle the view changes """
        self.index = index
        return super(SelectableLabel, self).refresh_view_attrs(rv, index, data)

    def on_touch_down(self, touch):
        """ Add selection on touch down """
        if super(SelectableLabel, self).on_touch_down(touch):
            return True
        if self.collide_point(*touch.pos) and self.selectable:
            return self.parent.select_with_touch(self.index, touch)

    def apply_selection(self, rv, index, is_selected):
        """ Respond to the selection of items in the view. """

        self.selected = not is_selected
        if is_selected:
            rv.data[index].update({'color': (1, 1, 1, 1)})
            self.refresh_view_attrs(RecycleViewWidget(), index, rv.data[index])
            print("selection changed to {0}".format(rv.data[index]))
            self.update_text_inputs()
        else:
            if rv.data[index].get("color") == (1, 1, 1, 1):
                rv.data[index].update({'color': (0, 0, 0, 1)})
                self.refresh_view_attrs(RecycleViewWidget(), index, rv.data[index])
        self.selected = not self.selected

    def update_text_inputs(self, *kwarg):
        my_text_input = MyFirstScreen().ids.system_name_text_input_id#<--i can access to widget
        print("my_print_val is:", my_text_input.text)#<--but widget's current text value is : ''
        # my_text_input.text = "Updated Value" 

main_style = Builder.load_file("test.kv")


class MyApp(App):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)

    def build(self):
        return main_style


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

<SelectableLabel>:
    canvas.before:
        Color:
            rgba: (0, 0, 1, 1) if self.selected else (1, 1, 1, 1)
        Rectangle:
            pos: self.pos
            size: self.size
<RecycleViewWidget>:
    viewclass: 'SelectableLabel'
    SelectableRecycleBoxLayout:
        default_size: None, dp(56)
        default_size_hint: 1, None
        size_hint_y: None
        height: self.minimum_height
        orientation: 'vertical'

<MyFirstScreen>:
    name: 'system_setup_page'
    system_name_text_input_id:system_name_text_input_id
    GridLayout:
        cols: 2
        BoxLayout:
            cols: 1
            padding: 20
            RecycleViewWidget:
        FloatLayout:
            Label:
                size_hint: None, None
                text: "Name:"
                font_size: 22
                pos_hint: {'center': (20/100, 90/100)}
            TextInput:
                id: system_name_text_input_id
                size_hint: None, None
                hint_text: "Type Your Name..."
                size: 200, 30
                multiline: False
                pos_hint: {'center': (65/100, 90/100)}
                on_text: root.get_text_inputs()
            Label:
                size_hint: None, None
                text: "User ID:"
                font_size: 20
                pos_hint: {'center': (20/100, 70/100)}
            TextInput:
                size_hint: None, None
                size: 200, 30
                hint_text: "Type Your ID..."
                pos_hint: {'center': (65/100, 70/100)}
    my_text_input = self.parent.parent.parent.parent.parent.system_name_text_input_id  
def update_text_inputs(self, *kwarg):
    #print('parent:', self.parent.parent.parent.parent.parent.system_name_text_input_id)
    #print('parent:', self.parent.parent.parent.parent.parent.system_name_text_input_id.text)

    my_text_input = self.parent.parent.parent.parent.parent.system_name_text_input_id 

    print("my_print_val is:", my_text_input.text)

    my_text_input.text = "Updated Value"