Kivy tutorial 005: A drawing app

Kivy tutorial 005: A drawing app – Kivy Blog

Central themes: Canvas instructions

中心主题: canvas 结构

The next couple of tutorials will move to a new application in order to showcase some more of Kivy’s core components. In this tutorial we’ll cover canvas instructions, Kivy’s low level drawing API which is always available. In the next two, we’ll add touch/mouse interaction to let you click to draw stuff, and then introduce kv language, and show how it interacts with Python code to easily produce guis without so much Python boilerplate.
下一个导师课将移动到一个新的应用程序为了展现一些kivy的核心部件。在这节导师课中我们将覆盖canvas结构,kivy的低层画画API, 这ZPI总是适合的。在下两节中,我们将添加 触摸/鼠标 互动来让你点击来画点什么玩意儿,并且然后介绍kv语言, 并且展现它是如何和python语言代码互动的来简单地生产gui,而不是如此多的python引用。

To showcase Kivy’s drawing API, our next app will be a simple drawing application. We’ll be making a widget gui to select a few different options (colour, size etc.), and handling the mouse/touch interaction manually to draw the result of user input.
为了展现kivy的画画API, 我们下一个app将是一个简单地画画应用程序。 我们将使一个组件gui选择一些不同的选择(颜色, 大小等等),并且手动地操控 鼠标/触摸 互动来绘画用户的输入结果。

We’ll need to start with a new basic app template, as introduced in the first couple of tutorials:
我们将需要来同一个基础的app模板开始,就像第一节导师课的介绍的一样:

from kivy.app import App


class DrawingApp(App):
    def build(self):
        return None

DrawingApp().run()

Before anything else, let’s start by getting some basic drawing working, with no other gui components. There isn’t a Widget for drawing already (there’s no nice way to abstract all the options you might want), so instead Kivy makes it easy to build your own Widget class:
在开始其他的事之前,让我们开始获得一些基础的绘画工作, 没有其它gui组件。 这不是一个组件来绘画(这不是一个好的方式来提取所有你想的选择), 因此替代kivy使它简单来创建你自己的组件类。

from kivy.uix.widget import Width

class DrawingWidget(Widget):
    pass

class DrawingApp(App):
    def build(self):
        return DrawingWidget()

DrawingApp().run()

You can run the app now, but the screen will just be black because Widget (and therefore DrawingWidget) doesn’t draw anything by default. We’re using Widget as the base class because we want to add it to the screen, but don’t need any extra behaviour beyond that.
你现在可以运行app,但是屏幕仍然是黑色的因为组件默认啥也没画。我们使用组件作为基类因为我们想要把它添加到屏幕里,但是不需要任何额外其他的行为。

Time to do our own drawing. Change your code to add the following:
是时候来做咱自己的画画了。改变你的代码以添加下面内容:

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

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

        with self.canvas:
            Color(1, 0, 0, 1)  # the arguments are red, blue,
                               # green, alpha
            Rectangle(size=(300, 100),
                      pos=(300, 200))


class DrawingApp(App):

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

DrawingApp().run()

If you run the app now, you’ll see a red rectangle. Its position in pixels will be 300 right and 200 up from the bottom left of the screen; Kivy’s coordinate system follows OpenGL in having its coordinate origin there.
如果你现在运行app。你将看到一个红色的矩形。 你以像素pixels为单位定位在举例屏幕的左下边的300右边,并且200上边的位置, kivy的坐标系统跟随OpenGL 一样有它自己的坐标源在这。

Rectangle in example app

This is the basic way of doing any kind of drawing, and with a combination of canvas instructions (also called graphics instructions) you can achieve any kind of gui result. In fact, anything you see drawn with Kivy is ultimately using canvas instructions, including all the built in widget classes!
这是做任何画画种类的基础方式,并且同一个canvas结构的组成,也被叫做图形结构,你可以完成任何gui结果。在事实上,你看到的同kivy的任何事最终使用canvas结构,包括所有在组件类内的建立。

The basic procedure always follows this one. First, open a with self.canvas block - this sets an internal variable that means all graphics instructions are drawn to the canvas of the current widget. All widgets have a canvas, you can draw on e.g. a Label or BoxLayout if you want. Second, instantiate any graphics instructions; in this case we use Color (which sets the colour of any following instructions) and Rectangle (which draws a rectangle at the given position). Any instructions you add later will be drawn on top of the previous ones.
基础方式总是跟随这个. 首先,打开一个  with self.canvas 区块-  这设置了一个内部的变量,这意味着所有图形指令都将绘制到当前小部件的画布上。

Try changing these arguments to modify what you see. The arguments to Color are red, green, blue and alpha components (currently opaque red). You can also try drawing other shapes by checking the vertex instruction documentation (vertex instructions are shapes, other instructions like Color are claled context instructions and include e.g. translation and rotation).
试着改变这些自变数来修改你看到的。颜色的自变数是红色,绿色,蓝色和alpha部件(目前是不透明的红色)。你也可以画其他的形状通过检查文档结构的顶部(结构的顶部是形状, 其他的结构像颜色是内容结构,并且包括了  比如说 平移  和旋转)

Note

As with several other things mentioned so far, canvas instructions have their own simple syntax for drawing in kv language, introduced in tutorial 7.
像目前几个其它的事儿提及的一样,画布结构有它们自己的简单地语法来在kv语言中画画,在导师课第7节中有介绍。

Note

You can also access self.canvas.before and self.canvas.after; everything in the former is drawn first, then everything in self.canvas, then everything in self.canvas.after. This helps you to draw in layers if necessary.
你也可以获取 self.canvas.before 和 self.canvas.after, 前者中的所有事物首先被画,然后是 self.canvas, 再然后 是 self.canvas.after。 有必要的画,这帮你来在不同的层上画画。

Let’s now draw a Rectangle filling the whole DrawingWidget, serving as the background of anything we draw:
让我们现在画一个正方形填充整个DrawingWidget,作为我们画的任何东西的背景:

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

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

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


class DrawingApp(App):

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

DrawingApp().run()

Surprise, it doesn’t work right! Although we set the rectangle size to self.size (the size of the DrawingWidget), and its pos to self.pos (the pos of the DrawingWidget), it always appears in the bottom left of the window and has size 100 pixels square. This is because although the DrawingWidget fills the window (because it is the root widget), its pos and size are not set until after its __init__ method has finished.
令人惊讶的是,它不能正常工作! 尽管我们设置矩形的size是 self.size (DrawingWidget的大小),并且它的位置是 self.pos(DrawingWidget的位置),它总是在窗口的左下角出现,并且有一个100像素的四方形。这是因为尽管DrawingWidget填充了窗口(因为它是根组件root widget),它的位置和大小没被设置直到它的__init__方法被完成。

Note

pos and size are two more Kivy properties that all widgets have. They give the position of the bottom left corner (in pixels) and the size of the Widget (also in pixels).
pos和size是所有组件有的kivy属性。它们提供位置是左下角(以像素为单位),组件的大小(同样也是以像素为单位)

To solve this problem, we again use event bindings:
为了解决这个问题,我们再一次使用event事件绑定:

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

This works just like in the previous tutorials; we’ve bound to the pos and size of the widget, and made it so that whenever they update the Rectangle is also updated. Remember, this is possible because pos and size are Kivy properties, which you can also bind to (the function is called when their value changes). When run, your app should now look like the following:
这就像之前的导师课中用的一样;我们已经绑定了组件的位置和大小,并且让它当组件的位置和大小属性更新时,矩形的也被更新。 记住,这是可能的,因为pos 位置 和size大小 都是kivy的属性,你也可以绑定(功能被叫唤当它们的值改变时)。当运行时,你现在的app也应该像下面这样:

Rectangle in example app

This tutorial has introduced the basic use of canvas instructions, including the notion of automatically updating them in response to gui changes, thanks to event binding. This is an important building block for building complex applications.
这节导师课已经介绍了canvas结构的基础使用,包括响应因GUI改变而自动地更新的概念,感谢event binding 事件绑定。 这是一个重要的建造模块来建立复杂的应用程序

In the next tutorial we’ll introduce mouse/touch input handling, so that we can finally draw something dynamicall in response to user input.
在下面的导师课中,我们将介绍  鼠标/触摸 输入操控,因此我们可以设置画些动态的事来响应用户的输入。

Full code

main.py:

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

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



class DrawingApp(App):

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

DrawingApp().run()

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

windows USB设备驱动开发通用技术

通用串行总线 (USB) 设备通过配置、接口、备用设置和终结点来定义其功能和功能,下面提供这些概念的高级概述。 常见 USB 方案 获取用于通信的设备句柄 ,并使用检索到的句柄或对象发送数据传输。 USB 描述符检索 以获取有关设备配置的信息、接口、设置及…

python基础语法 003-3 数据类型元组

1 元组 1.1 元组含义 1.1.1 元组的表示 #元组的表示方法:() names ("xiaoyun", "xiaoming") print(names)--结果------- (xiaoyun, xiaoming) 1.1.2 空元组 #空元组 names () print(type(names)) print(len(names))----------------结果--------- &l…

Profibus DP主站转Modbus模块连接马达保护器案例

一、概述 在工业自动化控制系统中,Profibus DP和Modbus是常见的通信协议,在同一现场还有可能遇到Modbus协议,ModbusTCP协议,Profinet协议,Profibus协议,Profibus DP协议,EtherCAT协议&#xff…

vant组件 顶部下拉刷新和页面底部下拉获取数据+顶部搜索框

1.html部分&#xff08;顶部tab切换无&#xff0c;只有主体list部分&#xff09; <div class"yd" ><!-- yd端 --><!-- 搜索框 --><van-searchv-model"ydsearchvalue"show-actionplaceholder"请输入搜索关键词"search"…

【ARM】Ulink不同的系列对于芯片的支持和可以支持keil软件

【更多软件使用问题请点击亿道电子官方网站】 1、 文档目标 了解不同版本的ULINK可以支持的芯片架构&#xff0c;和ULINK可以和哪个系列的keil软件进行在线调试 2、 问题场景 用于了解不同ULINK仿真器对于芯片的支持是不一样的&#xff0c;并不是ULINK可以支持所有的keil软件…

qmt量化交易策略小白学习笔记第44期【qmt编程之期货行情数据】

qmt编程之获取期货行情数据 qmt更加详细的教程方法&#xff0c;会持续慢慢梳理。 也可找寻博主的历史文章&#xff0c;搜索关键词查看解决方案 &#xff01; 获取行情数据 提示 使用该接口时&#xff0c;需要先订阅实时行情(subscribe_quote)或下载过历史行情(download_hi…

贪心算法——加工木棍(C++)

上大学&#xff0c;一天是一天&#xff0c;两天也是一天。 ——2024年6月27日 之前考试周断更了&#xff0c;今天重新开始&#xff01; 题目描述 有n根木棍&#xff0c;已知每根木棍的长度和重量。这些木棍在木工机器上加工&#xff0c;机器准备加工木棍需要一些时间&#xf…

YOLOv8数据集标注

1 简介 数据集是必不可少的部分&#xff0c;数据集的优劣直接影响训练效果。一般来说&#xff0c;一个完整的数据集应该包括训练集、测试集和验证集。通常&#xff0c;数据集会被划分为训练集和测试集&#xff0c;比如将数据集的70%用作训练集&#xff0c;30%用作测试集。在进行…

深度学习在蛋白质结构预测的新突破:AlphaFold、RoseTTAFold与ESMFold

在蛋白质结构预测和功能预测领域&#xff0c;基于机器学习的方法最近取得了显著的进展。特别是深度学习技术在这个领域中展现出了强大的能力&#xff0c;代表性的技术有 DeepMind 的 AlphaFold 和 RoseTTAFold。这些技术利用了大量的生物数据和先进的神经网络架构&#xff0c;极…

【科学计算与可视化】3. Matplotlib 绘图基础

安装 pip install matplotlib 官方文档 https://matplotlib.org/stable/api/pyplot_summary.html 主要介绍一些图片绘制的简要使用&#xff0c;更加详细和进阶需要可参考 以上官方文档。 1 绘制基础 方法名说明title()设置图表的名称xlabel()设置 x 轴名称ylabel()设置 y 轴…

在vscode 中ssh连接虚拟ubuntu,不能使用code打开文件

这是参考别人的文章&#xff1a;https://blog.csdn.net/weixin_44465434/article/details/130035032找到vscode的版本信息&#xff0c;提交后面是需要的打开home/(用户)/.bashrc&#xff0c;添加环境变量 export PATH"~/.vscode-server/bin/5437499feb04f7a586f677b155b03…

6.22套题

B. Dark 题意&#xff1a;每次能在数列中能使相邻两个数-1&#xff0c;求当数列没有连续非0值的最小贡献 解法:设表示前i个数中前i-1个数是否为0&#xff0c;当前数是j的最小贡献。表示i1以后减掉d的最小贡献。 C. 幸运值 D. 凤凰院真凶

Docker 日志

日志记录是任何生产应用程序中至关重要的一部分。当出现问题时&#xff0c;日志可以是恢复服务的关键工具&#xff0c;所以它们需要做好。在 Linux 系统上&#xff0c;我们期望通过一些常见方式与应用程序日志交互&#xff0c;有些方式更好。如果您在一台计算机上运行应用程序进…

文华财经盘立方均线-支撑压力自动画线多空声音预警指标公式源码

文华财经盘立方多空均线-支撑压力自动画线指标公式源码&#xff1a; //MA5:MA(C,5); //MA10:MA(C,10); MA20:MA(C,20),COLORRED; MA60:MA(C,60),COLORGREEN; TY:CLOSE; HD:FILTER(BACKSET(FILTER(REF(TY,10)HHV(TY,2*101),10),101),10); LD:FILTER(BACKSET(FILTER(REF(T…

openlayer 图层绘制成多种颜色的一个图层

技术栈&#xff1a; 因为是旧项目的优化功能&#xff0c;这里主要介绍实现思路。技术栈&#xff1a;openlayer 6.5^、jquery、layui组件。 背景&#xff1a; 在创建一个地图对象后&#xff0c;如何创建此处省略。这里主要讲解如何根据接口的数据来把水深测量时间的图层根据不同…

vue2的待办事项案例

头部组件 <template><div class"todo-header"><input type"text" placeholder"请输入你的任务名称&#xff0c;按回车键确认" keyup.enter"add"/></div> </template><script>import {nanoid} fro…

智能语音抽油烟机:置入WTK6900L离线语音识别芯片 掌控厨房新风尚

一、抽油烟机语音识别芯片开发背景 在繁忙的现代生活中&#xff0c;人们对于家居生活的便捷性和舒适性要求越来越高。传统的抽油烟机操作方式往往需要用户手动调节风速、开关等功能&#xff0c;不仅操作繁琐&#xff0c;而且在烹饪过程中容易分散注意力&#xff0c;增加安全隐…

【5G射频基本架构】

平台框架 平台演进及搭配 5G NR频谱 NSA/SA/ENDC

Java登录管理功能的自我理解(尚庭公寓)

登录管理 背景知识 1. 认证方案概述 有两种常见的认证方案&#xff0c;分别是基于Session的认证和基于Token的认证&#xff0c;下面逐一进行介绍 基于Session 基于Session的认证流程如下图所示 该方案的特点 登录用户信息保存在服务端内存&#xff08;Session对象&#xff…

安全技术和防火墙(iptables)

安全技术 入侵检测系统&#xff1a;特点是不阻断网络访问&#xff0c;主要是提供报警和事后监督&#xff0c;不主动介入&#xff0c;类似于监控。 入侵防御系统&#xff1a;透明模式工作&#xff0c;对数据包&#xff0c;网络监控&#xff0c;服务攻击&#xff0c;木马&#…