Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/python-2.7/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 在单独的.kv文件中为小部件创建属性_Python_Python 2.7_Kivy - Fatal编程技术网

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

Python 在单独的.kv文件中为小部件创建属性,python,python-2.7,kivy,Python,Python 2.7,Kivy,我正在学习编写Kivy应用程序。我创建了一个由两个网格布局组成的玩具应用程序。一个包含两个按钮,另一个包含两个标签。任务是在单击按钮时修改标签。当所有的布局都在同一个.kv文件中时,我可以非常简单地做到这一点,只需以标准方式创建id和属性 当我将布局拆分为单独的.kv文件时,我不能做同样的事情。我想这样做,因为我实际工作的项目太复杂,无法包含在单个.kv文件中。这是我的代码: 主要python代码: # filename DynamicApp.py import kivy kivy.requir

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

当我将布局拆分为单独的.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:
#文件名:dynamiccapp.kv
#:kivy 1.9.0
:
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"
#文件名:myfirstgrid.kv
#:kivy 1.9.0
id:\u我的\u第一个\u网格
行数:1
科尔斯:2
标签:
id:_标签_1
文字:“你好,世界”
标签:
id:_标签_2
文字:“你好,世界”
第二格的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
#文件名:myseoncdgrid.kv
#:kivy 1.9.0
#:导入mybutton mybutton
尺寸提示:0.25,0.25
pos_提示:{'center_x':0.5,'y':0}
行数:1
科尔斯:2
我的按钮:
文字:“做它”
标签\u 1:\u标签\u 1
我的按钮:
文本:“再做一次”
标签2:\u标签2
mybutton.py控制按钮操作,此处不显示,因为我无法在mybutton小部件中创建属性和引用,因为它会给我错误
NameError:name'\u label\u 2'未定义

我做了完全相同的策略,但所有的kv都在一个文件中,效果很好

如何在其他.kv文件中创建小部件的引用和属性

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


感谢

根据上的文档,“id的范围仅限于其声明的规则”。这意味着标签ID在
之外无效。这是有意义的,因为规则可以应用于任何UI树中的小部件,并且它不能提前知道自身之外存在什么或不存在什么

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

ex(未经测试):

类动态CAPP(应用程序):
label1=StringProperty(“Hello World”)
label2=StringProperty(“Hello World”)
def生成(自):
返回DynamicWidgets()
...
行数:1
科尔斯:2
标签:
文本:app.label1
标签:
文本:app.label2
...
尺寸提示:0.25,0.25
pos_提示:{'center_x':0.5,'y':0}
行数:1
科尔斯:2
我的按钮:
文字:“做它”
按:app.label1=“做到了”
我的按钮:
文本:“再做一次”
按:app.label2=“再做一次”

所以我想我已经能够回答我自己的问题了。正如我的直觉告诉我的那样,您实际上可以在不同的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

谢谢,我想我感到困惑的是,如果所有的.kv都保存在同一个文件中,那么我就可以按照自己的意愿设置属性。毕竟,这些小部件都是
的子部件,以此类推,只是为了方便起见,kv被保存在不同的文件中。你认为用我的方式而不是你的方式做有利弊吗?应用程序实际上是一个玩具,实际上,按钮将以更深刻的方式修改标签或其他小部件(设置可见性等)。ID的范围成为规则本身的原因是规则是一个模块化组件。在您的例子中,您知道这些小部件都是
的子部件,但是Kivy通常不能做出这样的假设,因为规则不知道它将被插入到哪里(它甚至可能没有父项)。就利/弊而言,我认为使用属性更干净一些(代码更少,您不必到处尝试跟踪ID)。它还使您在代码中更容易访问,您只需要访问属性,而不是手动引用小部件树。第二种方法也更为脆弱,如果重新排列UI,所有引用都将中断,需要重新编写。请注意,您不必将所有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