【问题标题】:Python framework Kivy didn't notice the file with extension .kvPython 框架 Kivy 没有注意到扩展名为 .kv 的文件
【发布时间】:2020-02-03 17:13:53
【问题描述】:

我对 Kivy 框架有疑问。我在文件 main.py 中定义了父类和子类。我还在文件 my.kv 中定义了子类并向他添加了两个小部件(标签和按钮)

main.py

from kivy.app import App 
from kivy.uix.boxlayout import BoxLayout 
from kivy.properties import ObjectProperty 

class MyApp(App):
    pass

class Child(BoxLayout):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)

class Parent(BoxLayout):

    obj = ObjectProperty(Child())

    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.add_widget(self.obj)


if __name__ == '__main__':
    MyApp().run()

我的.kv

Parent:

<Child>:
    Label:
        text: "Some text"
    Button:
        text: "Button"

我将子类定义为父类的属性,并在初始化期间将其添加到父类。但是在启动程序后,我没有看到之前添加的小部件(标签和按钮)。我看到展示的只是空的小部件。好像文件 my.kv 被简单地忽略了。请告诉我,怎么了。

【问题讨论】:

    标签: python kivy


    【解决方案1】:

    问题在于:

    obj = ObjectProperty(Child())
    

    在加载my.kv 文件之前进行评估,因此此时没有将LabelButton 添加到Child 实例的规则。这会产生一个Child 实例,它是一个空的BoxLayout。当MyApp 启动时,它会加载my.kv 文件,并创建Parent 实例作为根小部件。它还会加载&lt;Child&gt; 规则,但这对存储在obj 属性中的已创建Child 实例没有影响。

    这可以通过许多不同的方式来解决。一种是在加载my.kv 文件之前不创建Child 实例。像这样:

    class Parent(BoxLayout):
    
        obj = ObjectProperty(None)   # initialize the obj to None
    
        def __init__(self, **kwargs):
            super().__init__(**kwargs)
    
            # create the Child instance now
            self.obj = Child()
    
            self.add_widget(self.obj)
    

    另一种方法是将Child 作为Parent 的子项包含在my.kv 文件中。

    或者您可以将&lt;Child&gt; 规则放在单独的kv 文件/字符串中,并在Child 的定义之后、Parent 的定义之前将其加载到您的.py 文件中。

    【讨论】:

      【解决方案2】:

      你的主要 python 文件和你的 kivy 文件的名称应该相同。

      如果您将 python 文件命名为“app.py”并将 kivy 文件命名为“kivy.kv”,则您的 python 文件将找不到 kivy 文件。

      但是,如果您将两个文件名命名为“app.py”和“app.kv”,python 文件将识别 kivy 文件并按预期执行。

      【讨论】:

      • 名为“MyApp”的应用程序类和名为 my.kv 的 kivy 语言文件。这意味着 my.kv 必须自动启动。
      【解决方案3】:

      只是在 Johns 的回答中添加一点:如果你想使用 kv lang ids 或类似的东西,你可以使用 on_kv_post

      例如,如果你有一个 kv:

      Parent:
          Child:
              id: child
      

      您可以通过 id 将其分配给您的父属性:

      class Parent(BoxLayout):
      
          obj = ObjectProperty() 
      
          def __init__(self,**kwargs):
              super(Parent,self).__init__(**kwargs)
      
          def on_kv_post(self,Parent):
              self.obj = self.ids.child
      

      这个事件对于在widget的kv加载后运行代码或触发其他功能很有用。

      【讨论】:

        【解决方案4】:

        有时会出现,请尝试手动加载:

        from kivy.lang import Builder
        ...
        class MyApp(App):
        ...
            def build(self):
                with open('my.kv', encoding='utf-8', errors='ignore') as kvfile:
                    Builder.load_string(kvfile.read())
        

        P.S.:你真的需要多次继承BoxLayout吗?

        【讨论】:

        • 是的。我需要它。
        • 嗯,可能是kv文件有问题。显示应用类和 kv 文件。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-12-24
        • 2012-12-24
        • 2019-07-07
        • 2017-05-03
        • 1970-01-01
        • 2017-06-27
        • 1970-01-01
        相关资源
        最近更新 更多