2015-10-15 98 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

相關問題