KIVY BLOG Kivy tutorial 007: Introducing kv language

news2024/12/25 22:28:58

Kivy tutorial 007: Introducing kv language – Kivy Blog

DECEMBER 18, 2019 BY ALEXANDER TAYLOR

Kivy tutorial 007: Introducing kv language
Kivy 导师课007: 介绍kv语言

Central themes: kv language, building a gui, integration with Python
中心主题:  kv语言, 建立一个gui, 和python 结合

The goal of this tutorial will be to build up a simple gui around the DrawingWidget built in the last two tutorials. A nice simple goal would be to let the user select the colour of the lines. Kivy actually has a ColorPicker Widget for this purpose (see the documentation), but we’ll skip that for now in order to continue demonstrating Kivy widget construction.
这节导师课的目的将是建立一个简单地gui围绕着 DrawingWidget 上两次导师课建立的。 一个好的简单地目标将是让用户选择颜色的线。 kivy 的确有一个ColorPicler 颜色选择器 组件 为了这个目的(看这个文档), 但是我们现在将跳过为了继续演示Kivy组件的结构。

Note

Since all Kivy widgets are built out of other Widgets and canvas instructions, you might like to think about how you’d build the ColorPicker from scratch.
自从kivy组件都是由其他的组件们 和画布结构构成的, 你可能像如何你从划拉中如何构建ColorPicker。

Let’s start with the code from last time, minus the now-unnecessary red Rectangle:
让我们同上次最后的代码开始, 略低于标准的现在不怎么必要的 红色矩形:

from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.slider import Slider

from kivy.uix.widget import Widget
from kivy.graphics import Rectangle, Color, Line

from random import random

class DrawingWidget(Widget):
    def __init__(self):
        super(DrawingWidget, self).__init__()

        with self.canvas:
            Color(1, 1, 1, 1)
            self.rect = Rectangle(size=self.size,
                                  pos=self.pos)
        self.bind(pos=self.update_rectangle,
                  size=self.update_rectangle)


    def update_rectangle(self, instance, value):
        self.rect.pos = self.pos
        self.rect.size = self.size

    def on_touch_down(self, touch):
        super(DrawingWidget, self).on_touch_down(touch)

        with self.canvas:
            Color(random(), random(), random())
            self.line = Line(points=[touch.pos[0], touch.pos[1]], width=2)

    def on_touch_move(self, touch):
        self.line.points = self.line.points + [touch.pos[0], touch.pos[1]]


class DrawingApp(App):

    def build(self):
        root_widget = DrawingWidget()
        return root_widget

DrawingApp().run()

I’ll demonstrate adding the new gui components in two ways; first in pure Python as has been demonstrated in previous tutorials, and second using kv language instead. So, here’s a Python implementation of the new features we want, beginning with importing the Widget classes we’ll need:

我将证明增加新的gui 组件在2种方式;  第一种是纯Python 作为在之前导师课中被证明的, 并且第二种使用kv语言相替代。 因此, 这是一个python我们想要的新特征的执行, 这从import我们需要导入widget类开始。
 

from kivy.uix.boxlayout import BoxLayout
from kivy.uix.label import Label
from kivy.uix.slider import Slider

Slider is a previously-unseen Widget displaying a draggable marker. We’ll be using a Slider for each primary colour (red, blue, green), and using this to set the Color when a Line is drawn.
slider 是一个以前地-不可见的 组件演示着一个可拖拽的制造者。 我们将使用一个Slider 给每个最基本的颜色(红,蓝,绿)并且使用这来设置颜色当一个线被绘画的时候。

We can now update the build method of DrawingApp, replacing the root widget and adding the new gui components:
我们现在可以更新DrawingApp绘画APP的build方法, 替代widget基类 和增加新的gui组件:

class DrawingApp(App):

    def build(self):
        root_widget = BoxLayout(orientation='vertical')

        drawing_widget = DrawingWidget()
        #To create a slider from 0 to 1 starting from 0.5:
        red_slider = Slider(min=0, max=1, value=0.5,
                            size_hint_y=None, height=80)
        green_slider = Slider(min=0, max=1, value=0.5,
                            size_hint_y=None, height=80)
        blue_slider = Slider(min=0, max=1, value=0.5,
                            size_hint_y=None, height=80)

        colour_row = BoxLayout(orientation='horizontal',
                               size_hint_y=None, height=80)
        colour_label = Label(text='output colour:')
        colour_widget = Widget()

        # We draw a Rectangle on colour_widget exactly the same way as
        # with DrawingWidget, just without making a new class
        with colour_widget.canvas:
            output_colour = Color(red_slider.value,
                                  green_slider.value,
                                  blue_slider.value)
            output_rectangle = Rectangle()
        def update_colour_widget_rect(instance, value):
            output_rectangle.pos = colour_widget.pos
            output_rectangle.size = colour_widget.size
        colour_widget.bind(pos=update_colour_widget_rect,
                           size=update_colour_widget_rect)

        def update_colour_widget_colour(instance, value):
            output_colour.rgb = (red_slider.value,
                                 green_slider.value,
                                 blue_slider.value)
        red_slider.bind(value=update_colour_widget_colour)
        green_slider.bind(value=update_colour_widget_colour)
        blue_slider.bind(value=update_colour_widget_colour)

        root_widget.add_widget(drawing_widget)
        root_widget.add_widget(red_slider)
        root_widget.add_widget(green_slider)
        root_widget.add_widget(blue_slider)
        root_widget.add_widget(colour_row)

        colour_row.add_widget(colour_label)
        colour_row.add_widget(colour_widget)

        return root_widget

This is a lot of code to drop all at once, but read it carefully and you’ll see that it’s only the same concepts already introduced: we instantiate Widgets, add them to one another, and create bindings so that things automatically happen when Kivy properties are changed. In this case, we make use of the value Kivy property of the Slider widget, which gives its current value (changing automatically when the slider is moved).
这是一次中途卸货的一些代码,但是阅读它谨慎地  并且 你将看到它只是已经介绍的相同的概念:我们举例说明组件, 增加它们给另一个, 并且创造bind关联因此物件儿们自动地发生当kivy 属性被改变的时候。 在这个案例中,我们利用了kivy slider组件的属性值, 这值提供它当前值(当slider被移动时,值自动地改变)。

Run the code and you should see something like the image below. You can update the colour in the bottom right by moving the sliders. Cool.

运行code 并且第你应该看到某事像下面图片一样。你可以更新颜色通过移动sliders在底部的右边,  帅。

A problem now becoming obvious is that all this code is kind of verbose, and also it can be a little unclear what is happening - Widget instantiation is in a different place to where the Widgets are added to one another, which is different again to where their events are bound. You can mitigate this with a careful app structure and following whatever coding conventions you like, but some of it is unavoidable given how Python works.
现在紧随而来的明显的问题是所有的代码是冗长啰嗦的一种,并且它也可以是一些不太清晰的当下发生的-  组件实例化时在一个不同的地方组件们被添加到另一个种, 这又不一样被加到它们事件被绑定的。 你可以缓和这同一个谨慎的app结构 并且跟随 你想插入的任何代码,但是它们的的一些是不可避免地被给出有关如何python运行的。

It’s for this reason that Kivy comes with kv language, a simple but powerful language specifically designed for creating Kivy widget trees. If learning a new language sounds worrying…don’t be concerned! Kv doesn’t have much special syntax and is targeted specifically at Kivy widgets, and much of the code you write is actually normal Python (we’ll see that soon).

因这个原因kivy有了kv语言,一个简单但是功能强大的语言被特别设计来创建kivy组件树。 如果学习一个新的语言听起来坏极了,  不需要考虑!  kv 没有很多的特殊语法 并且在kivy组件中被 定为目标, 并且一些代码你写的 是真正的常见的python。

All of the kv language stuff discussed below is documented on the Kivy website; I’ll cover the basics, but you can find more information there.

所有的kv语言物件儿 在下面的kivy网页文档中被讨论, 我将涉及基础的,但是你可以发现更多的信息在这。

First, get rid of all the Python code from above, and replace the root widget return with the following:
首先, 摆脱所有的python代码从上述的代码中, 并且替代root widget 返回在下面:

class Interface(BoxLayout):
    pass

class DrawingApp(App):

    def build(self):
        root_widget = Interface()
        return root_widget

kv language works by writing rules for Widget classes, which will be automatically applied every time you instantiate one. We can use kv for almost everything added to the app so far, but this time we’ll construct the gui step by step to see how each part is added with the new kv syntax. We’ll be writing a kv rule for the new Interface class.
kv 语言通过编写给Widget 组件类的规则工作,  每次你实例化这组件类 将被自动地应用。我们可以使用kv 给最常用的每个物件增加到app, 但是这次我们将组成gui 一步又一步的来看看被添加的每部分伴随着新的kv语法。我们将给新的界面类编写新的kv规则。

To start using kv language, write the following code in a file named drawing.kv. This name comes from the name of the App class, minus the App at the end if present, and in lowercase (e.g. if you named your App MySuperKivyApp you’d need to name the file mysuperkivy.kv). This is only necessary if you want the file to be automatically loaded, you can also load files or string manually. Our first kv code is:
为了开始使用kv语言,编写接下来的代码在一个名为drawing.kv的文件种。 这名字从App类获得,如果存在的话最终略低于标准的App, 并且在一个小写的(例如:  如果你命名你的App MySuperKivyApp, 你需要命名这个文件为 mysuperkivy.kv) 如果你想这文件被自动加载,这是唯一必须的, 你也可以 加载文件 或者字符串管理。 我们第一个kv编码是:

<Interface>:
    orientation: 'vertical'
    Label:
        text: 'label added with kv'
        font_size: 50

Run the code again, and you should see the a Label with the given text, as the kv file is automatically loaded and its <Interface> rule applied.

再次运行代码, 并且你应该看到标签同时被给予了text文本, 作为kv文件时自动加载的并且它的 <Interface>规则应用。

Label added with kv rule.

This demonstrates the core rules of kv syntax. A kv rule is created with the <WidgetName>: syntax. You can make a rule for any widget, including built in ones (Kivy internally has a large kv file), and if you make multiple rules for the same Widget then all of them are applied one by one.
这证明了kv语法的代码规则。 一个kv 规则同<>: 语法被创造。 你可以为任何组件指定一个规则,包括内置的一个(kivy内部有一个巨大的kv文件), 并且如果你制造多个规则给相同一个组件,然后所有的规则会一个接一个应用。

Below the rule creation, we indent by 4 spaces and define values for Kivy properties of the widget, and add child widgets. Lines like orientation: 'vertical' set Kivy properties just like we did previously in the Python code. Note that everything to the right of the colon is normal Python code - that doesn’t matter here, but for instance we could equally well write orientation: ''.join(['v', 'e', 'r', 't', 'i', 'c', 'a', 'l']) and it would be exactly the same. You can set any Kivy property of a widget in this way, finding the available options in the documentation as previously discussed.
下面是规则创建,我们缩进4个空格 并且 给kivy的组件定义值, 并且添加子类组件。 Lines 像orientation:'vertical' 设置Kivy属性就像我们之前在python代码中做的一样。 注意冒号:的右边的任何事是常见的Python代码, 这并不是很重要,但是例如  我们也可以写orientation: ''.join(['v', 'e', 'r', 't', 'i', 'c', 'a', 'l']) 并且他可能是真的一样。 在这方式你可以设置一个组件的任何kivy属性, 在之前讨论的文件中找到适合的选择。

We can also add child widgets by writing the widget name with a colon, then indenting by a further 4 spaces, as is done here with the Label. After this you can keep going as deep as you like, setting properties or adding more child widgets.
我们也可以增加子类组件通过编写 冒号:和组件名字,然后进一步的缩进4个空格,像这儿这已经写得Label标签一样。 在这之后你可以继续所心所欲的探索,设置多个属性 或者添加更多的子类组件。

We can use these pieces of syntax to construct the previous Python interface entirely in kv:
我们可以使用这些语法囫囵地来组建先前的python 界面在kv中:

<Interface>:
    orientation: 'vertical'
    DrawingWidget:
    Slider:
        min: 0
        max: 1
        value: 0.5
        size_hint_y: None
        height: 80
    Slider:
        min: 0
        max: 1
        value: 0.5
        size_hint_y: None
        height: 80
    Slider:
        min: 0
        max: 1
        value: 0.5
        size_hint_y: None
        height: 80
    BoxLayout:
        orientation: 'horizontal'
        size_hint_y: None
        height: 80
        Label:
            text: 'output colour:'
        Widget:

This hasn’t yet set up the event binding, but the full widget tree has been constructed entirely using the kv syntax described above. The immediate advantage of this is that kv language directly expresses the widget tree - there are no longer separate steps for instantiating Widgets, setting their properties and adding them to one another. Instead, you get to see everything at once.
这还没设置任何bind绑定,但是整个组件树已经在上述中被使用kv语法整个创建了。kv语言直接表达组件树 是kv语言最直觉的优势, 在组件树种没有更长独立的步骤给实例组件,设置它们的属性,并且增加它们到另一个种。 反而, 你开始一次看到任何事物。

This gui doesn’t yet have the behaviour of the Python one (i.e. having the sliders control output colour), but in the interest of keeping these tutorials relatively short, I’ll stop here for now. In the next tutorial will see how kv language also makes event binding very easy.
这个gui没有python行为(有sliders 控制output颜色),但是保持这导师课的相对较短,我将在这就停止了,在下面的导师课中将看到如何kv语言并且使事件相绑定,非常简单。

Full code

main.py:

from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.slider import Slider

from kivy.uix.boxlayout import BoxLayout
from kivy.uix.label import Label
from kivy.uix.slider import Slider

from kivy.uix.widget import Widget
from kivy.graphics import Rectangle, Color, Line

from random import random

class DrawingWidget(Widget):
    def __init__(self):
        super(DrawingWidget, self).__init__()

        with self.canvas:
            Color(1, 1, 1, 1)
            self.rect = Rectangle(size=self.size,
                                  pos=self.pos)
        self.bind(pos=self.update_rectangle,
                  size=self.update_rectangle)

    def update_rectangle(self, instance, value):
        self.rect.pos = self.pos
        self.rect.size = self.size

    def on_touch_down(self, touch):
        super(DrawingWidget, self).on_touch_down(touch)

        if not self.collide_point(*touch.pos):
            return

        with self.canvas:
            Color(random(), random(), random())
            self.line = Line(points=[touch.pos[0], touch.pos[1]], width=2)

    def on_touch_move(self, touch):
        if not self.collide_point(*touch.pos):
            return

        self.line.points = self.line.points + [touch.pos[0], touch.pos[1]]


class Interface(BoxLayout):
    pass

class DrawingApp(App):

    def build(self):
        root_widget = Interface()
        return root_widget

DrawingApp().run()

drawing.kv:

<Interface>:
    orientation: 'vertical'
    DrawingWidget:
    Slider:
        min: 0
        max: 1
        value: 0.5
        size_hint_y: None
        height: 80
    Slider:
        min: 0
        max: 1
        value: 0.5
        size_hint_y: None
        height: 80
    Slider:
        min: 0
        max: 1
        value: 0.5
        size_hint_y: None
        height: 80
    BoxLayout:
        orientation: 'horizontal'
        size_hint_y: None
        height: 80
        Label:
            text: 'output colour:'
        Widget:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1850270.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

qt 简单实验 一个可以向左侧拖拽缩放的矩形

1.概要 向左拖拽矩形&#xff0c;和向右拖拽不同&#xff0c;向右拖拽是增加宽度&#xff0c;向左拖拽是增加宽度的同时还要向左移动x的坐标。 2.代码 2.1 resizablerectangleleft.h #ifndef RESIZABLERECTANGLELEFT_H #define RESIZABLERECTANGLELEFT_H #include <QWid…

win10系统还原怎么操作?超实用的四个系统一键重装方法来了

在我们使用电脑的日常生活中&#xff0c;Win10系统可能会出现各种问题&#xff0c;比如系统运行缓慢、程序崩溃或者遭受了恶意软件的攻击。为了解决这些问题&#xff0c;系统还原是一种非常有效的方法&#xff0c;能够让您快速地将系统恢复到之前的正常状态。而如今&#xff0c…

[保姆级教程]uniapp自定义标签页切换组件

文章目录 导文样式改成动态列表切换点击效果加上点击自动滑动scroll-view加上切换组件效果 导文 unaipp自带的标签页和ui设计相差太大&#xff0c;直接修改组件比手写一个还麻烦&#xff0c;下面手写一个。 样式 先用scroll-view做一个滑动&#xff0c;不然多的话滑动不了。 &l…

共93本!全网最全Frontiers旗下期刊2022、2023版影响因子和分区对比完整版目录!

本周投稿推荐 SSCI • 1区&#xff0c;4.0-5.0&#xff08;无需返修&#xff0c;提交可录&#xff09; EI • 各领域沾边均可&#xff08;2天录用&#xff09; CNKI • 7天录用-检索&#xff08;急录友好&#xff09; SCI&EI • 4区生物医学类&#xff0c;0.1-0.5&…

Android jetpack Room的简单使用

文章目录 项目添加ksp插件添加 room 引用开始使用room1. 创建bean2. 创建 dao类3. 创建database类 数据库升级复制数据库到指定路径参考文献 项目添加ksp插件 注意&#xff0c;因为ksp插件 是跟项目中使用的kotlin的版本要保持一致的&#xff0c;否则会报错的 首先我们去 https…

HTML静态网页成品作业(HTML+CSS)——家乡泉州介绍网页(3个页面)(表格布局)

&#x1f389;不定期分享源码&#xff0c;关注不丢失哦 文章目录 一、作品介绍二、作品演示三、代码目录四、网站代码HTML部分代码 五、源码获取 一、作品介绍 &#x1f3f7;️本套采用HTMLCSS&#xff0c;table布局&#xff0c;未使用Javacsript代码&#xff0c;共有3个页面。…

Vue75-路由传参3

一、在index.js中使用props参数 1-1、写法一&#xff1a;值为对象 此时&#xff0c;参数是固定写死的&#xff0c;不推荐&#xff01; 1-2、值为布尔值 此时只能收到params中的参数&#xff01; 1-3、值为函数 &#xff08;最强大&#xff09; 二、小结

什么是新媒体矩阵?如何搭建?

什么是新媒体&#xff1f; 新媒体矩阵作用 新媒体矩阵账号类型 搭建新媒体矩阵步骤

Autosar Dcm配置-0x23服务ReadMemoryByAddress-基于ETAS软件

文章目录 前言Dcm配置DcmDsdDcmDspDcmDspMemoryIdInfo 代码分析总结 前言 一般在调教开发阶段&#xff0c;会使用XCP进行观测和标定&#xff0c;本质上也是操作指定的内存地址。量产后&#xff0c;一般XCP会取消。本文介绍的UDS ReadMemoryByAddress服务&#xff0c;也是读取内…

第9章 项目管理概论 (项目管理原则)

第9章 项目管理概论 9.7项目管理原则&#xff0c;在第三版教材第344~349页&#xff1b; 文字图片音频方式 第一个知识点&#xff1a;根据环境进行裁剪 (关注的)关键点 每个项目都具有独特性 项目成功取决于适合项目的独特环境和方法 裁剪应该在整个项目进展过程中持续进行第二…

AUCell和AddModuleScore函数进行基因集评分

AUCell 和AddModuleScore 分析是两种主流的用于单细胞RNA测序数据的基因集活性分析的方法。这些基因集可以来自文献、数据库或者根据具体研究问题进行自行定义。 AUCell分析原理&#xff1a; 1、AUCell分析可以将细胞中的所有基因按表达量进行排序&#xff0c;生成一个基因排…

atcoder abc 358

A welcome to AtCoder Land 题目&#xff1a; 思路&#xff1a;字符串比较 代码&#xff1a; #include <bits/stdc.h>using namespace std;int main() {string a, b;cin >> a >> b;if(a "AtCoder" && b "Land") cout <&…

车辆轨迹预测系列 (三):nuScenes数据集详细介绍-1

车辆轨迹预测系列 (三)&#xff1a;nuScenes数据集详细介绍-1 文章目录 车辆轨迹预测系列 (三)&#xff1a;nuScenes数据集详细介绍-1一、数据集准备1、解压2、安装nuscenes-devkit3、介绍 二、架构内容解释1、category 类别2、attribute 属性3、visibility 可见性4、instance …

【金】01Y120 pygame 外星人入侵

13241890059 具有功能&#xff1a;分数记录、排行榜、难度升级 ‪H:\0work\1_pygame-200

emWin在Windows上仿真运行环境配置

文章目录 一、emWin介绍二、emWin必用的2个工具2.1 PC仿真器2.2 GUIBuilder图形化设计工具三、安装VS2022四、打开emwin仿真工程五、常见的配置修改5.1 运行内存修改5.2 LCD显示屏尺寸的修改一、emWin介绍 emWin(Embedded Wizard Graphics Library)是Segger公司开发的嵌入式…

Redis实战—Redis分布式锁

本博客为个人学习笔记&#xff0c;学习网站与详细见&#xff1a;黑马程序员Redis入门到实战 P56 - P63 目录 分布式锁介绍 基于Redis的分布式锁 Redis锁代码实现 修改业务代码 分布式锁误删问题 分布式锁原子性问题 Lua脚本 编写脚本 代码优化 总结 分布式锁介绍…

transdreamer 论文阅读笔记

这篇文章是对dreamer系列的改进&#xff0c;是一篇world model 的论文改进点在于&#xff0c;dreamer用的是循环神经网络&#xff0c;本文想把它改成transformer&#xff0c;并且希望能利用transformer实现并行训练。改成transformer的话有个地方要改掉&#xff0c;dreamer用ht…

Large Language Model based Multi-Agents: A Survey of Progress and Challenges

目录 摘要简介背景单一智能体系统单智能体 vs .多智能体系统 剖析多智能体系统&#xff1a;接口、剖析、通信和能力智能体 - 环境接口智能体画像智能体通信能力获取 摘要 大型语言模型( Large Language Models&#xff0c;LLMs )在各种任务中都取得了令人瞩目的成功。由于LLMs…

Linux搭建我的世界乌托邦探险之旅3.2整合包服务端,Minecraft开服教程

Linux服务器使用MCSM10 搭建 我的世界 乌托邦探险之旅3.2 整合包 服务端 的教程&#xff0c;Minecraft整合包开服教程。 大型养老探险整合包&#xff1a;乌托邦探险之旅3.2&#xff0c;探索上千种结构&#xff0c;造访丰富的自然群系&#xff0c;欣赏生动的生物动画&#xff0…

Android SurfaceFlinger——屏幕热插拔回调(九)

上一篇文章分析了回调注册监听的调用流程&#xff0c;对于数据的回调正好是注册监听的逆向调用。首先前面提到过在 HWC2On1Adapter 中就会直接转型为每一个回调到上层&#xff0c;这里我们就看一下屏幕热插拔回调&#xff08;hotplugHook&#xff09;的调用流程。 一、硬件回调…