将kv语言与Python代码链接
我在一些基础示例中学到了如何通过ID将kv文件和Python代码连接起来,下面是一个简单的例子:
看看我在my.kv文件中的代码:
<MyFirstWidget>:
# both these variables can be the same name and this doesn't lead to
# an issue with uniqueness as the id is only accessible in kv.
txt_inpt: txt_inpt
Button:
id: f_but
TextInput:
id: txt_inpt
text: f_but.state
on_text: root.check_status(f_but)
在myapp.py文件中:
class MyFirstWidget(BoxLayout):
txt_inpt = ObjectProperty(None)
def check_status(self, btn):
print('button state is: {state}'.format(state=btn.state))
print('text input text is: {txt}'.format(txt=self.txt_inpt))
这段代码可以正常工作,也就是说我们可以通过txt_inpt来访问Label。我想在我的代码中对一个按钮做同样的事情,但我遇到了一个错误:
play_Button.text = 'hello'
错误信息是:'kivy.properties.ObjectProperty'对象没有'text'这个属性。
看看下面的代码:
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.properties import ObjectProperty
from kivy.graphics import Color
gui = '''
<MenuScreen>:
play_Button: playButton
GridLayout:
size_hint: .2, .2
pos_hint: {'center_x': .5, 'center_y': .5}
rows: 1
Button:
id: playButton
text: 'Play !'
'''
class MenuScreen(Screen):
play_Button = ObjectProperty(None)
def __init__(self, **kwargs):
super(MenuScreen, self).__init__(**kwargs)
#If i use below one it works
#self.ids.playButton.text = 'hello'
Builder.load_string(gui)
play_Button.text = 'hello'
pass
class MyJB(App):
def build(self):
sm = ScreenManager()
sm.add_widget(MenuScreen(name='menu'))
return sm
if __name__ == '__main__':
MyJB().run()
如果我使用ids.play_Button,它就能按预期工作,但我觉得我在其他方式上做错了什么。有人能给点建议吗?
1 个回答
2
class MenuScreen(Screen):
play_Button = ObjectProperty(None)
def __init__(self, **kwargs):
super(MenuScreen, self).__init__(**kwargs)
#If i use below one it works
#self.ids.playButton.text = 'hello'
Builder.load_string(gui)
play_Button.text = 'hello'
pass
这里的缩进有点问题,play_Button.text
这一行应该放在 __init__
方法里(而且 pass
其实没什么用,可以删掉)。这是 Stack Overflow 上的笔误,还是你实际代码里的问题呢?
如果这是你实际代码里的问题,那就会导致你看到的错误,因为这段代码在类被声明的时候就运行了,而不是在你创建这个类的实例时运行。这意味着它看不到对象的属性,只能看到 ObjectProperty 本身……而根据错误信息,它没有 'text' 这个属性。
通常来说,把 kv 字符串加载到你应用的 build
方法里,或者干脆放在任何类之外会更合适。