2015-10-15 93 views
1

我正在学习编写Kivy应用程序。我创建了一个由两个网格布局组成的玩具应用程序。一个包含两个按钮,另一个包含两个标签。任务是在点击按钮时修改标签。通过简单地以标准方式创建ID和属性,当所有布局都在同一个.kv文件中时,我能够很简单地做到这一点。在单独的.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   
<[email protected]>   
    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 
<[email protected]> 
    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文件中创建对小部件的引用和属性。

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

感谢

回答

1

据有关Kv Language的文档,“这个ID在范围上仅限于它在声明的规则”。这意味着标签ID在<My*[email protected]>之外无效。这是有道理的,因为规则可以应用于任何UI树中的小部件,并且它不能提前知道存在或不存在于其外部的东西。

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

EX(未经测试):

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

... 

<[email protected]>   
    rows: 1 
    cols: 2 
    Label: 
     text: app.label1 
    Label: 
     text: app.label2 

... 

<[email protected]> 
    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" 
+0

谢谢,我想我发现令人困惑的是,如果所有。 kv保存在同一个文件中,然后我可以根据需要设置属性。毕竟,这些组件都是'的子组件,为了方便起见,它只是将kv保存在不同的文件中。 –

+0

你认为有这样做的优点和缺点,而不是你的方式吗?该应用程序实际上是一种玩具,实际上按钮会以更深刻的方式修改标签或其他小部件(设置可见性等) –

+0

规范本身的范围原因是该规则是模块化组件。在*你的情况下,你知道这些组件都是''''''的子组件,但是Kivy无法做出一般的假设,规则不知道它将被插入到哪里(它可能不会甚至有父母)。 – bj0

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   
<[email protected]>   
    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 
<[email protected]> 
    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 
+0

请注意,您不必将小部件上的所有ID都分配给属性,可以通过以下方式轻松访问它们:http://kivy.org/docs/guide/lang.html#accessing-widgets-defined-inside -kv琅在你的蟒蛇码 – bj0

相关问题