我正在尝试为我的一个小项目学习Kivy api,但是我陷入了这个问题,我实际上不知道自己是否在朝着正确的方向前进。
我创建了一个继承自Widget的自定义类,其中包含一些我知道会重复很多的东西:
#classes.py
from kivy.uix.widget import Widget
from kivy.uix.gridlayout import GridLayout
from kivy.uix.label import Label
from kivy.uix.textinput import TextInput
from kivy.properties import ObjectProperty
from kivy.properties import StringProperty
class TextField(Widget):
field_id = ObjectProperty(None)
field_text = StringProperty('Label: ')
field_placeholder = StringProperty('your text here')
grid = GridLayout(cols=2)
label = Label(text=field_text)
tinput = TextInput(id=field_id, text=field_placeholder)
grid.add_widget(label)
grid.add_widget(tinput)
然后我想在kv文件中创建类的实例
#main.kv
<MainLayout>
cols:3
TextField:
field_id:'someid'
field_text:'My Label: '
field_placeholder: 'My placeholder'
现在,问题是当我运行它时,我得到:
ValueError: Label.text accept only str
当我打印field_text时,我得到
<StringProperty name=>
所以我猜它不是str,就像错误说的那样。我只是完全误解了财产吗?我想用其他方式做些什么吗?
提前感谢您的时间!
编辑:我能想到的唯一问题就是入口点。
#main.py
import kivy
kivy.require('1.8.0')
from example.exampleapp import ExampleApp
if __name__ == "__main__":
ExampleApp().run()
#exampleapp.py
from example.classes import *
from kivy.uix.gridlayout import GridLayout
with open('zapador/kv/main.kv', encoding='utf8') as f:
Builder.load_string(f.read())
class Mainlayout(GridLayout):
pass
class ExampleApp(App):
def build(self):
return Mainlayout()
答案 0 :(得分:0)
您的代码的一个问题是TextField
中的代码部分,其中似乎是您试图定义自定义类的布局:
grid = GridLayout(cols=2)
label = Label(text=field_text)
tinput = TextInput(id=field_id, text=field_placeholder)
grid.add_widget(label)
grid.add_widget(tinput)
如果要在python中定义布局,则必须在__init__()
方法内部的方法中进行。但是,如果执行此操作,则在text
方法中设置的__init__()
字段将被设置为StringProperty
属性的初始值,并且不会更新StringProperty
已更改(除非您添加更多代码来处理该事件并修改关联的text
属性)。
一种更好,更简单的方法是在kv
中进行布局,并在kv
更改时让text
处理StringProperty
属性的更新。因此,我建议将您的TextField
类更改为:
#classes.py
from kivy.uix.widget import Widget
from kivy.properties import ObjectProperty
from kivy.properties import StringProperty
class TextField(Widget):
field_id = ObjectProperty(None)
field_text = StringProperty('Label: ')
field_placeholder = StringProperty('your text here')
并在main.kv
中定义布局:
#main.kv
<MainLayout>
cols:3
TextField:
# field_id:'someid'
field_text:'My Label: '
field_placeholder: 'My placeholder'
<TextField>:
field_id: ti
GridLayout:
cols: 2
Label:
text: root.field_text
TextInput:
id: ti
text: root.field_placeholder
通过这种安排,对StringProperty
的更改将反映在text
内部的TextField
属性中。请注意,我没有将您的field_id
ObjectProperty
用作id
的{{1}}。我认为不可能将TextInput
用作ObjectProperty
。我已将您的id
field_id
用作ObjectProperty
TextInput
的引用