在单独的.kv文件中为小部件创建属性

时间:2015-10-15 14:51:51

标签: python python-2.7 kivy

我正在学习写Kivy应用程序。我创建了一个由两个网格布局组成的玩具应用程序。一个包含两个按钮,另一个包含两个标签。任务是在单击按钮时修改标签。通过简单地以标准方式创建id和属性,当所有布局都在同一个.kv文件中时,我就能够做到这一点。

当我将布局拆分为单独的.kv文件时,我无法做同样的事情。我想这样做,因为我实际工作的项目太复杂,不能包含在单个.kv文件中。所以这是我的代码:

主要的python代码:

# filename DynamicApp.py
import kivy
kivy.require('1.9.0')

from kivy.app import App
from kivy.uix.relativelayout import RelativeLayout
from kivy.lang import Builder

Builder.load_file("myfirstgrid.kv")
Builder.load_file("mysecondgrid.kv")

class DynamicWidgets(RelativeLayout):
    pass

class DynamicApp(App):
    def build(self):
        return DynamicWidgets()

if __name__ == "__main__":
    DynamicApp().run()

基础kivy文件:

# File name: DynamicApp.kv
#:kivy 1.9.0
<DynamicWidgets>:
    MyFirstGrid:

    MySecondGrid:

第一个网格的kivy

# File name: myfirstgrid.kv
#:kivy 1.9.0        
<MyFirstGrid@GridLayout>        
    id: _my_first_grid
    rows: 1
    cols: 2
    Label:
        id: _label_1
        text: "Hello World"
    Label:
        id: _label_2
        text: "Hello World"

第二个网格的Kivy

# File name: myseoncdgrid.kv
#:kivy 1.9.0
#:import mybutton mybutton
<MySecondGrid@GridLayout>   
    size_hint: 0.25, 0.25
    pos_hint: {'center_x': 0.5, 'y' : 0}
    rows: 1
    cols: 2
    MyButton:
        text: 'Do it'
        label_1: _label_1
    MyButton:
        text: 'Do it Again'
        label_2: _label_2

mybutton.py控制按钮操作,此处未显示,因为我无法在MyButton窗口小部件中创建属性和引用,因为它给出了错误NameError: name '_label_2' is not defined

我做了完全相同的策略但是在单个文件中使用了所有kv并且它很好。

如何为其他.kv文件中的窗口小部件创建引用和属性。

我觉得我错过了一些基本的东西。

由于

2 个答案:

答案 0 :(得分:1)

根据Kv Language上的文档,&#34; id的范围受限于它在&#34;中声明的规则。这意味着标签ID在<My*Grid@GridLayout>之外无效。这是有道理的,因为规则可以应用于任何UI树中的小部件,并且它不能提前知道存在或不存在于其自身之外。

问题的解决方案是使用Properties。您可以将标签文本绑定到StringProperty,然后当您在代码中更改它时(按下按钮),Kivy将为您更新标签。如果您不能轻易地相互引用小部件,则可以将属性放在App对象上,该对象始终以kv为app引用。

ex(未经测试):

class DynamicApp(App):
    label1 = StringProperty("Hello World")
    label2 = StringProperty("Hello World")
    def build(self):
        return DynamicWidgets()

...

<MyFirstGrid@GridLayout>        
    rows: 1
    cols: 2
    Label:
        text: app.label1
    Label:
        text: app.label2

...

<MySecondGrid@GridLayout>   
    size_hint: 0.25, 0.25
    pos_hint: {'center_x': 0.5, 'y' : 0}
    rows: 1
    cols: 2
    MyButton:
        text: 'Do it'
        on_press: app.label1 = "did it"
    MyButton:
        text: 'Do it Again'
        on_press: app.label2 = "did it again"

答案 1 :(得分:0)

所以我想我能够回答我自己的问题。事实上,你似乎可以像我直觉告诉我的那样在不同的KV文件中引用id。您只需要确保正确管理引用:

# File name: DynamicApp.kv
#:kivy 1.9.0
<DynamicWidgets>:
    MyFirstGrid:
        id: _my_first_grid
        my_second_grid: _my_second_grid
    MySecondGrid:
        id: _my_second_grid
        my_first_grid: _my_first_grid
# File name: myfirstgrid.kv
#:kivy 1.9.0        
<MyFirstGrid@GridLayout>        
    id: _my_first_grid
    label_1: _label_1
    label_2: _label_2
    rows: 1
    cols: 2
    Label:
        id: _label_1
        text: "Hello World"
    Label:
        id: _label_2
        text: "Hello World"
# File name: myseoncdgrid.kv
#:kivy 1.9.0
#:import mybutton mybutton
<MySecondGrid@GridLayout>   
    size_hint: 0.25, 0.25
    pos_hint: {'center_x': 0.5, 'y' : 0}
    rows: 1
    cols: 2
    MyButton:
        text: 'Do it'
        on_press: self.onClick1(*args)
    MyButton:
        text: 'Do it Again'
        on_press: self.onClick2(*args)
#file button.py
from kivy.uix.button import Button

class MyButton(Button):
    def onClick1(self, instance):
        print 'OK'
        mfg = self.parent.my_first_grid
        mfg.label_1.text = "Hello Universe"
        return True
    def onClick2(self, instance):
        mfg = self.parent.my_first_grid
        mfg.label_2.text = "Hello Galaxy"
        return True