1. 随机颜色

通过前面的教程,咪博士已经带大家实现了画板的绘图功能。但是,现在画板只能画出黄色的图案,还十分单调,接下来咪博士就教大家,如何使用随机颜色,让画板变得五彩斑斓。

改进后的代码如下:

  1. from random import random
  2.  
  3. from kivy.app import App
  4. from kivy.uix.widget import Widget
  5. from kivy.graphics import Color, Ellipse, Line
  6.  
  7. class MyPaintWidget(Widget):
  8. def on_touch_down(self, touch):
  9. color = (random(), random(), random())
  10. with self.canvas:
  11. Color(*color)
  12. d = 30.
  13. Ellipse(pos=(touch.x - d / 2, touch.y - d / 2), size=(d, d))
  14. touch.ud['line'] = Line(points=(touch.x, touch.y))
  15.  
  16. def on_touch_move(self, touch):
  17. touch.ud['line'].points += [touch.x, touch.y]
  18.  
  19. class MyPaintApp(App):
  20. def build(self):
  21. return MyPaintWidget()
  22.  
  23. if __name__ == '__main__':
  24. MyPaintApp().run()

试试看。怎么样?是不是好看多了呢?

第 1 行  from random import random  我们导入了随机函数 random,它可以产生 [0, 1) 之间的随机数

第 10 行  color = (random(), random(), random())  通过调用 random 函数,产生随机的 RGB 分量,存储在元组 color 中。后面(第 12 行),我们会用随机的 RGB 分量合成随机的颜色。注意,第 10 行的代码位于 on_touch_down 函数内。所以,用户每次点击鼠标的时候,都会生成新的随机 RGB 分量。

第12 行,用前面(第 10 行)产生的随机 RGB 分量生成随机颜色 color。函数 Color 需要授受 3 个参数(分别表示 RGB 的 3 个分量)。这里的 Color(* color)  表示将元组 color 解包,传递给函数 Color。由于元组 color 包含 3 个元素,所以它解包之后,就产生了 3 个随机数,而这 3 个随机数恰好可以做为 RGB 的 3 个分量传递给函数 Color。

不过,由于现在的颜色是完全随机的,程序有时候会产生一些比较暗的颜色,在黑色的画板背景上显示效果不是很好。我们可以进一步限制随机颜色的取值范围,让它只取一些比较鲜亮的颜色。

  1. from random import random
  2.  
  3. from kivy.app import App
  4. from kivy.uix.widget import Widget
  5. from kivy.graphics import Color, Ellipse, Line
  6.  
  7. class MyPaintWidget(Widget):
  8. def on_touch_down(self, touch):
  9. color = (random(), 1, 1)
  10. with self.canvas:
  11. Color(*color, mode='hsv')
  12. d = 30.
  13. Ellipse(pos=(touch.x - d / 2, touch.y - d / 2), size=(d, d))
  14. touch.ud['line'] = Line(points=(touch.x, touch.y))
  15.  
  16. def on_touch_move(self, touch):
  17. touch.ud['line'].points += [touch.x, touch.y]
  18.  
  19. class MyPaintApp(App):
  20. def build(self):
  21. return MyPaintWidget()
  22.  
  23. if __name__ == '__main__':
  24. MyPaintApp().run()

试试调整后的代码。哇!顿时鲜艳多了。

第 10 行  color = (random(), 1, 1)  我们将随机颜色的后 2 个分量固定为 1,只让第 1 个分量随机变化。

第 12 行  Color(*color, mode='hsv')  我们用 mode=’hsv’,指定颜色采用 HSV 模式,而不是先前默认的 RGB 模式。HSV 色彩模式的 3 个参数,分别代表 色调(Hue)、饱和度(Saturation)、明度(Value)。色调(Hue) 表示不同的色调(色彩的种类和名称);饱和度(Saturation) 越高,则颜色越深、越艳;明度(Value)表示颜色的明度程度。由于采用了 HSV 色彩模式,第 10 行代码产生的随机元组 color 的含义也要相应发生变化了。color 中的第 1 参数是一个随机数,表示随机选择不同的色彩种类;第 2 个参数,固定为 1,表示取最大的饱和度,即将颜色调到最深、最艳;第 3 个参数,也固定取 1,表示将颜色调到最亮。这样改进之后,程序就只会生成明亮的随机颜色了。

2. 清除按钮

最后,我们要在画板上添加一个清除按钮,这样用户不必重启程序,就能将画板清空,并绘制新的图形。

完整代码如下:

  1. from random import random
  2.  
  3. from kivy.app import App
  4. from kivy.uix.widget import Widget
  5. from kivy.uix.button import Button
  6. from kivy.graphics import Color, Ellipse, Line
  7.  
  8. class MyPaintWidget(Widget):
  9. def on_touch_down(self, touch):
  10. color = (random(), 1, 1)
  11. with self.canvas:
  12. Color(*color, mode='hsv')
  13. d = 30.
  14. Ellipse(pos=(touch.x - d / 2, touch.y - d / 2), size=(d, d))
  15. touch.ud['line'] = Line(points=(touch.x, touch.y))
  16.  
  17. def on_touch_move(self, touch):
  18. touch.ud['line'].points += [touch.x, touch.y]
  19.  
  20. class MyPaintApp(App):
  21. def build(self):
  22. parent = Widget()
  23. self.painter = MyPaintWidget()
  24. clearbtn = Button(text='Clear')
  25. clearbtn.bind(on_release=self.clear_canvas)
  26. parent.add_widget(self.painter)
  27. parent.add_widget(clearbtn)
  28. return parent
  29.  
  30. def clear_canvas(self, obj):
  31. self.painter.canvas.clear()
  32.  
  33. if __name__ == '__main__':
  34. MyPaintApp().run()

点击左下角的清除(Clear)按钮,可以将画板的内容清空。

第 5 行  from kivy.uix.button import Button  导入 Button 类。窗体左下角的清除 (Clear) 按钮,便是 Button 类的实例。

第 24 行 parent = Widget() 创建一个空的窗口部件 (Widget)。后面我们会将自定义窗口部件(画板 MyPaintWidget)以及清除按钮(Button)添加到 parent 上。注意:Kivy 中进行窗口部件编排的标准做法是使用布局( layout)。咪博士这里用的是比较便捷(但不规范)的方法,为的是让大家快速完成简易画板这个项目。关于 Kivy 中布局(layout)的使用,咪博士将在其他的教程中专门讲解。

第25 行 self.painter = MyPaintWidget() 创建自定义窗口部件对象,并赋值给变量 self.painter。因为,后面我们还要在别的函数中引用它。

第 26 行 clearbtn = Button(text='Clear') 创建清除按钮对象,将按钮的文字设置为 Clear,并赋值给变量 clearbtn。

第 27 行 clearbtn.bind(on_release=self.clear_canvas) 将清除按钮的 on_release 事件绑定 (bind) 到 self.clear_canvas 方法(第 32, 33 行)。这样,当用户按下并释放清除按钮时,将触发按钮的 on_release 事件,然后调用该事件所绑定的 self.clear_canvas 方法,执行清除画板的动作。

第 28, 29 行,将自定义窗口部件对象(self.painter)和清除按钮对象(clearbtn)添加到 parent 窗口部件中。

第 30 行 return parent 返回 parent 窗口部件。注意,此时的 parent 已经包含了自定义窗口部件对象(self.painter)和清除按钮对象(clearbtn)。

第 32, 33 行,是用户按下并释放清除按钮时触发的回调函数。清除画板的功能正是通过第 33 行 self.painter.canvas.clear() 实现的。

好啦,到此为止 Kivy 简易画板的项目就全部完成啦。请关注咪博士后续更加精彩的 Kivy 教程。

原文链接:http://www.ipaomi.com/2017/11/20/kivy-中文教程-实例入门-简易画板-simple-paint-app:3-随机颜色及清/

Kivy 中文教程 实例入门 简易画板 (Simple Paint App):3. 随机颜色及清除按钮的更多相关文章

  1. Kivy 中文教程 实例入门 简易画板 (Simple Paint App):1. 自定义窗口部件 (widget)

    1. 框架代码 用 PyCharm 新建一个名为 SimplePaintApp 的项目,然后新建一个名为 simple_paint_app.py 的 Python 源文件, 在代码编辑器中,输入以下框 ...

  2. Kivy 中文教程 实例入门 简易画板 (Simple Paint App):2. 实现绘图功能

    1. 理解 kivy 坐标系统 上一节中,咪博士带大家实现了画板程序的基础框架,以及一个基本的自定义窗口部件(widget).在上一节的末尾,咪博士留了一道关于 kivy 坐标系统的思考题给大家.通过 ...

  3. Kivy 中文教程 实例入门 简易画板 (Simple Paint App):0. 项目简介 & 成果展示

    本教程咪博士将带领大家学习创建自己的窗口部件 (widget).最终,我们完成的作品是一个简易的画板程序. 当用 kivy 创建应用时,我们需要仔细思考以下 3 个问题: 我们创建的应用需要处理什么数 ...

  4. Kivy crash 中文教程 实例入门 1. 第1个应用 Kivy App (Making a simple App)

    1.  空白窗口 在 PyCharm 中创建一个名为 TutorialApp 的项目,然后在该项目中新建了个名为 tutorial_app.py 的 Python 源文件,在 PyCharm 的代码编 ...

  5. Python Kivy 中文教程:安装(Windows)

    Kivy 是一套用于跨平台快速应用开发的开源框架,只需编写一套代码,便可运行于各大桌面及移动平台上(包括 Linux, Windows, OS X, Android, iOS, 以及 Raspberr ...

  6. wxPython中文教程 简单入门加实例

    wx.Window 是一个基类,许多构件从它继承.包括 wx.Frame 构件.技术上这意味着,我们可以在所有的 子类中使用 wx.Window 的方法.我们这里介绍它的几种方法: * SetTitl ...

  7. android用户界面详尽教程实例

    android用户界面详尽教程实例 1.android用户界面之AlarmManager教程实例汇总http://www.apkbus.com/android-48405-1-1.html2.andr ...

  8. android用户界面的教程实例---转自qianqianlianmeng的博客

    1.android用户界面之AlarmManager教程实例汇总http://www.apkbus.com/android-48405-1-1.html2.android用户界面之文本编辑教程实例汇总 ...

  9. wxPython中文教程入门实例

    这篇文章主要为大家分享下python编程中有关wxPython的中文教程,分享一些wxPython入门实例,有需要的朋友参考下     wxPython中文教程入门实例 wx.Window 是一个基类 ...

随机推荐

  1. 浅淡个人学习嵌入式Linux过程

    我专业是电子信息工程,在初入大学的时候,我们的班主任便要我们多多去了解一些关于电子方面的知识.后来我了解到了嵌入式,继而了解到了嵌入式Linux.其实我们学习linux差不多就学习linux内核,但是 ...

  2. Luogu P1525 关押罪犯

    传送门 首先 这是一个并查集= = 这道题其实明白了还挺简单的qwq 思路: 因为只看仇恨值最大的一对儿,所以把他们从大到小排序,越大的就尽量分开,直到不能再分为止qwq q[x]表示x最大的敌人(x ...

  3. 2-(基础入门篇)Air202下载开发入门(给Air202下载第一个程序)

    http://www.cnblogs.com/yangfengwu/p/8887933.html 资料链接 链接:https://pan.baidu.com/s/1-SRfsKGQ7rZVvFmp1O ...

  4. TCP/IP与OSI模型

  5. SerialPort.h SerialPort.cpp

    SerialPort.h 1 #ifndef __SERIALPORT_H__ 2 #define __SERIALPORT_H__ 3 4 #define WM_COMM_BREAK_DETECTE ...

  6. SpringBoot favicon.ico

    默认的favicon.ico spring boot 默认输出spring的logo, 可以使用spring.mvc.favicon.enabled=false将其关闭 ############### ...

  7. Luogu P3455 [POI2007]ZAP-Queries

    由于之前做了Luogu P2257 YY的GCD,这里的做法就十分套路了. 建议先看上面一题的推导,这里的话就略去一些共性的地方了. 还是和之前一样设: \[f(d)=\sum_{i=1}^a \su ...

  8. Linux常用命令行

    实时查看日志runtime.log最后100行 tail -f -n 100 runtime.log

  9. 将 C# 枚举序列化为 JSON 字符串 实践

    一.定义枚举 public enum SiteTypeEnum { 中转部 = 1, 网点 = 2 } 还有 BooleanEnum 和 OptTypeEnum 这两个枚举,这里暂且省略了它们的定义. ...

  10. 【nodejs】让nodejs像后端mvc框架(asp.net mvc )一样处理请求--控制器的声明定义和发现篇(3/8)

    文章目录 前情概要 前面文章把路由已经介绍的差不多了,包括url映射,路由选择等.接下来讲一讲controller的一些基本规则 BaseController的所有代码都在这里拉.相当简单. 主要逻辑 ...