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 8 class MyPaintWidget(Widget): 9 def on_touch_down(self, touch): 10 color = (random(), random(), random()) 11 with self.canvas: 12 Color(*color) 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 21 class MyPaintApp(App): 22 def build(self): 23 return MyPaintWidget() 24 25 26 if __name__ == '__main__': 27 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 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 21 class MyPaintApp(App): 22 def build(self): 23 return MyPaintWidget() 24 25 26 if __name__ == '__main__': 27 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 9 class MyPaintWidget(Widget): 10 def on_touch_down(self, touch): 11 color = (random(), 1, 1) 12 with self.canvas: 13 Color(*color, mode='hsv') 14 d = 30. 15 Ellipse(pos=(touch.x - d / 2, touch.y - d / 2), size=(d, d)) 16 touch.ud['line'] = Line(points=(touch.x, touch.y)) 17 18 def on_touch_move(self, touch): 19 touch.ud['line'].points += [touch.x, touch.y] 20 21 22 class MyPaintApp(App): 23 def build(self): 24 parent = Widget() 25 self.painter = MyPaintWidget() 26 clearbtn = Button(text='Clear') 27 clearbtn.bind(on_release=self.clear_canvas) 28 parent.add_widget(self.painter) 29 parent.add_widget(clearbtn) 30 return parent 31 32 def clear_canvas(self, obj): 33 self.painter.canvas.clear() 34 35 36 if __name__ == '__main__': 37 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-随机颜色及清/