Kivy:无法更新其他类的文本输入值 [英] Kivy: Can't update text input value from another class
问题描述
我是kivy
的新手.我正在尝试从另一个类更改文本输入值(TextInput
框中显示的字符串值),但没有任何反应.
I'm new on kivy
.I'm trying to change text input value (the string value that is shown in TextInput
box) from another class, But nothing passes.
我在class MyFirstScreen
中有以下小部件:
- 一个
RecycleView
具有多个项目(每个项目是一个dictionary
) - 两个
TextInput
s
- One
RecycleView
with multiple items (each item is adictionary
) - Two
TextInput
s
我想要做的:在
What I want to do: When each items in RecycleView
selected, TextInput
s should be update and load with corresponding values of selected item's dictionary
.
但是当我尝试从另一个类(class SelectableLabel
)访问当前TextInput
的值时:
But when i try to access current TextInput
's value from another class (class SelectableLabel
):
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"
我可以访问my_text_input
小部件,但其文本(my_text_input.text
)是一个空字符串(''
).此外,当我更改my_text_input.text
的值时,TextInput
的框中没有任何反应.
I can access to my_text_input
widget but its text (my_text_input.text
) is an empty string (''
).Furthermore when i change the value of my_text_input.text
, nothing happens in TextInput
's box.
有人知道我在这里做错什么或如何做这项工作吗?预先谢谢你...
Does anyone know what am I doing wrong here or how to make this work? Thank you in advance...
这是我的.py代码:
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()
以及我的.kv代码:
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)}
推荐答案
问题是因为在update_text_inputs()
中使用MyFirstScreen()
可以创建类MyFirstScreen
的新实例,但是必须使用现有实例.
Problem is because using MyFirstScreen()
in update_text_inputs()
you create new instance of class MyFirstScreen
but you have to use existing instance.
应该是更好的方法,但是目前我唯一的想法是为此使用parent
.
It should be better way to get it but at this moment my only idea is to use parent
for this .
因为这些元素之间有许多小部件,所以它需要许多parent
:
Because there are many widgets between these elements so it needs many parent
:
my_text_input = self.parent.parent.parent.parent.parent.system_name_text_input_id
我使用print(self.parent)
,下一个print(self.parent.parent)
等找到了它.
I found it using print(self.parent)
, next print(self.parent.parent)
, etc.
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"
这篇关于Kivy:无法更新其他类的文本输入值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!