如何在kivy中正确导入自定义小部件

Posted

技术标签:

【中文标题】如何在kivy中正确导入自定义小部件【英文标题】:How to correctly import custom widgets in kivy 【发布时间】:2019-05-13 04:40:35 【问题描述】:

我有一个小部件 (W2),由其他小部件 (W1) 组成。每个都有一个对应的 .kv 文件,如下所示。运行 main.py,我希望看到带有两个标签的黑色背景,垂直堆叠。相反,我将两个标签放在一起,所以出了点问题。

kivy.factory.FactoryException: Unknown class <W1>

所以我想,“也许我应该在 w2.py 中导入 w1.py,即使它没有在 py 文件中明确使用?那......有点工作。我把两个标签放在一起,就像下图。

我做错了什么?编写预期将由另一个小部件导入/包含的小部件的正确方法是什么?以及正确的导入方式?

我尝试在 .py 文件中使用 Builder.load_file() 并仅导入 .py 文件,但结果相似。

w1.py:

import kivy
from kivy.properties import StringProperty
from kivy.uix.widget import Widget
kivy.require('1.10.0')

class W1(Widget):
    text = StringProperty('default')

    def __init__(self,  **kwargs):
        super(W1, self).__init__(**kwargs)

w1.kv:

#:kivy 1.10.0

<W1>:
    text:
    Label:
        text: root.text

w2.py:

import kivy from kivy.uix.boxlayout import BoxLayout
# from w1 import W1  # added this to get a working, but the incorrect layout
kivy.require('1.10.0')

class W2(BoxLayout):

    def __init__(self,  **kwargs):
        super(W2, self).__init__(**kwargs)

w2.kv:

#:kivy 1.10.0
#:include w1.kv

<W2>:
    orientation: 'vertical'
    W1:
        text: 'w1.1' 
    W1:
        text: 'w1.2'

ma​​in.py:

import kivy
from w2 import W2
from kivy.app import App
kivy.require('1.10.0')


class mainApp(App):

    def build(self):
        pass


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

ma​​in.kv:

#:kivy 1.10.0
#:include w2.kv

W2:

编辑 重叠已解决,但可能不正确。我的 W1 继承自 BoxLayout 而不是 Widget,我认为基 Widget 类中可能缺少最小高度/宽度属性。

我仍然不确定处理导入具有配对 .kv 文件的小部件的“正确”方法是什么,或者当我从 Widget 继承时为什么会得到重叠的小部件;只是猜测。

【问题讨论】:

【参考方案1】:

为什么要为此使用两个不同的 kv 文件? 我会说正确的方法类似于我的 kv 文件。因为您将可以在单个页面上完成的事情分开,如果您需要不同的页面,您可以使用ScreenManager import stuff

ma​​in.py

`
import kivy
from kivy.app import App
from kivy.uix.widgets import Widget
from kivy.uix.label import Label
from kivy.uix.gridlayut import GridLayout

class MyGrid(Widget):
     pass


class MyApp(App):
     def build(self):

 # this calls what we want to show in the kv file
         return MyGrid()



if __name__ == "__main__":
MyApp().run()
`

文件是这样写的,因为App掉了,为了链接2它必须具有相同的名称

my.kv: # "" 基本上从 .py 文件链接MyGrid 然后显示 # 网格布局等 网格布局: 行数:2

        Label:
           text: "whatever"
        
        Label:
           text: "whatever 2"

   

【讨论】:

是的,我的具体示例可以在单个页面中完成。这是一个最小可行的例子,但假设我有一个小部件,我希望在我的项目中的许多不同的小部件中。关键是我(我什至不再使用 kivy...)试图做一些不能(或不应该)在单个页面中完成的事情。

以上是关于如何在kivy中正确导入自定义小部件的主要内容,如果未能解决你的问题,请参考以下文章

在 Kivy 中使用 RecycleView 的自定义小部件的对齐问题

使用自定义小部件 kivy

带有 kivy 语言和自定义小部件的 Kivy 滚动视图

如果未动态添加,如何正确删除Kivy中的小部件

如何在不导入自定义小部件类包的情况下使用自定义小部件和 uic.loadUi?

Kivy:如何使小部件表现得像溢出:隐藏