首页 > 解决方案 > Kivy - 我如何找出 .kv 文件中 Widget 的路径

问题描述

在我的 python 代码中,我能够通过使用 self.canvas.before 在 .kv 文件中定义的小部件中画一条线。

然后,在 .kv 中,我将 Widget 移动到 TabbedPanelItem 内,但它不再正常工作。

self.canvas.before 不是正确的路径,我应该改用什么?什么是正确的路径?

一般来说,我如何找出层次结构?.kv 文件中的那些对象是由构建器创建的(如果我的理解是正确的),我如何弄清楚如何将 python 代码绑定到构建器创建的对象。感谢您的任何帮助。

主要.py:

class SampBoxLayout(BoxLayout):
    def __init__(self, **kwargs):
        super(SampBoxLayout, self).__init__(**kwargs)
        with self.canvas.before:
            self.myline=Line(points=(100,100,400,500), close=False, width=2)

主文件

SampBoxLayout:
<SampBoxLayout>:
    orientation: "vertical"
    padding: 0
    spacing: 0
    TabbedPanel:
        do_default_tab: False
        TabbedPanelItem:
            text: "noc_clk"
            BoxLayout:
                orientation: "vertical"
                Widget:
                    height: "440dp"
                    size_hint_y: None
                    canvas:
                        Color:
                            rgba: 0, 0, 0, 0.5
                TabbedPanel:
                    do_default_tab: False
                    TabbedPanelItem:
                        text: "Node0"
                        BoxLayout:
                            orientation: "horizontal"

标签: pythonkivy

解决方案


实际上,即使添加了 kv 文件,您的应用程序仍然可以正常运行。这条线正在 SampBoxLayout 的画布上绘制,但它不可见,因为每个小部件的不透明度为 1.0,即不透明。下面的示例,为了显示绘制的线条,我opacity = 0.5TabbedPanel.

层次结构/路径

Kv 语言 » 规则上下文

Kv 语言特有的三个关键字:

app:总是指您的应用程序的实例。

root:指当前规则中的基本小部件/模板

self:始终引用当前小部件

值表达式、on_property 表达式、id 和保留关键字

自己

关键字 self 引用“当前小部件实例”:

Button:
    text: 'My state is %s' % self.state

此关键字仅在规则定义中可用,表示规则的根小部件(规则的第一个实例):

<MyWidget>:
    custom: 'Hello world'
    Button:
        text: root.custom

应用程序

此关键字始终指代您的应用实例。它相当于在 Python 中调用kivy.app.App.get_running_app() 。

Label:
    text: app.name

将 Python 代码绑定到在 kv 文件中创建的对象

方法一

  • 在类级别声明一个 ObjectProperty 并将其连接到id在 kv 文件中创建的对象。这是最佳实践方法。

主文件

from kivy.properties import ObjectProperty


class SampBoxLayout(BoxLayout):
    tp = ObjectProperty(None)

主文件

<SampBoxLayout>:
    tp: tp
    orientation: "vertical"
    padding: 0
    spacing: 0

    TabbedPanel:
        id: tp
        opacity: 0.5

方法二

  • 添加id到在 kv 文件中创建的对象并使用self.ids.id-nameself.ids['id-name']

最佳实践与速度

笔记

尽管 self.ids 方法非常简洁,但通常认为使用 ObjectProperty 是“最佳实践”。这将创建一个直接引用,提供更快的访问并且更明确。

例子

主文件

from kivy.base import runTouchApp
from kivy.uix.boxlayout import BoxLayout
from kivy.graphics import Line
from kivy.lang import Builder


class SampBoxLayout(BoxLayout):
    def __init__(self, **kwargs):
        super(SampBoxLayout, self).__init__(**kwargs)
        with self.canvas.before:
            self.myline=Line(points=(100, 100, 400, 500), close=False, width=2)


if __name__ == "__main__":
    runTouchApp(Builder.load_file('main.kv'))

主文件

SampBoxLayout:
<SampBoxLayout>:
    orientation: "vertical"
    padding: 0
    spacing: 0

    TabbedPanel:
        opacity: 0.5
        do_default_tab: False

        TabbedPanelItem:
            text: "noc_clk"
            BoxLayout:
                orientation: "vertical"
                Widget:
                    height: "440dp"
                    size_hint_y: None
                    canvas:
                        Color:
                            rgba: 0, 0, 0, 0.5
                TabbedPanel:
                    do_default_tab: False
                    TabbedPanelItem:
                        text: "Node0"
                        BoxLayout:
                            orientation: "horizontal"

输出

画线


推荐阅读