python - 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"
解决方案
实际上,即使添加了 kv 文件,您的应用程序仍然可以正常运行。这条线正在 SampBoxLayout 的画布上绘制,但它不可见,因为每个小部件的不透明度为 1.0,即不透明。下面的示例,为了显示绘制的线条,我opacity = 0.5
在TabbedPanel
.
层次结构/路径
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
方法一
- 在类级别声明一个 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-name
或self.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"
输出
推荐阅读
- bash - 使用 sed (或类似的)删除重复模式之间的任何内容
- date - 为什么我们说“最后修改”而不是“最新修改”?
- mysql - 如何在存储过程中通过以逗号分隔的id对连续多条记录进行分组?
- java - 如何在 Java EE 应用程序中将请求代理到具有丰富标头的另一个位置
- fusionauth - 如何在没有 FusionAuth 发送邮件的情况下生成邮件验证或忘记密码的令牌?
- ios - 架构 x86_64 的未定义符号:“_OBJC_CLASS_$_OPPCheckoutProvider”,引用自
- selenium-webdriver - 无法通过浏览器堆栈本地测试在移动真实设备上从我的本地机器上传文件
- php - 购物车页面在 Dreamhost 网络服务器中无法正常工作
- database - Joomla article 3.X - Hot to define a img article for a external run
- google-chrome - http://localhost:8080 在 catalina 和 chrome81 中重定向到 https://localhost:8080