将kv语言与Python代码链接

0 投票
1 回答
3148 浏览
提问于 2025-04-18 01:07

我在一些基础示例中学到了如何通过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 方法里,或者干脆放在任何类之外会更合适。

撰写回答