Kivy 简明教程

Kivy - Drawing App

在本章中,我们将学习开发一个简单的 Kivy 应用程序,用户可以通过拖动鼠标按钮,绘制出不同尺寸和颜色的实心矩形和圆(椭圆)。

用户从矩形/椭圆的左上角将鼠标指针拖动到右下角。以下代码的开发中使用的方法是在 touch_down 事件和 touch_up 事件中捕获鼠标坐标。因此,我们在 App 类的 build() 方法中使用以下代码启动程序 −

def build(self):
   self.w= Widget()
   self.w.bind(on_touch_down=self.on_touch_down)
   self.w.bind(on_touch_up=self.on_touch_up)
   return(self.w)

我们希望用户可以选择绘制矩形或圆形。需要添加三个切换按钮,用于选择绘制矩形、绘制圆形或清除画布。因此,我们将 App 窗口的布局更改为 box 布局,将 Widget 对象添加到顶部,并在其下方放置三个按钮。

lo = BoxLayout(orientation='vertical')

self.w = Widget()
self.w.bind(on_touch_down=self.on_touch_down)
self.w.bind(on_touch_up=self.on_touch_up)
lo.add_widget(self.w)

hlo = BoxLayout(orientation='horizontal', size_hint=(1, .1))

self.b2 = ToggleButton(text='Circle', group='mode')
self.b1 = ToggleButton(text='Rectangle', state='down', group='mode')
self.b3 = ToggleButton(text='Clear', group='mode')

hlo.add_widget(self.b1)
hlo.add_widget(self.b2)
hlo.add_widget(self.b3)
lo.add_widget(hlo)

return lo

要绘制所需的形状,我们需要捕获鼠标在按下的位置和松开的位置。

on_touch_down() 方法很简单 −

def on_touch_down(self, *args):
   self.td = args[1].pos

所有处理都发生在 on_touch_up() 方法中。捕获的按下事件坐标和松开事件坐标用于计算矩形或圆形的尺寸。

对于圆,x 半径、y 半径和中心如下计算 −

self.tu=args[1].pos
   xr = (self.tu[0]-self.td[0])/2
   yr = (self.td[1]-self.tu[1])/2
   c=(self.td[0]+xr, self.td[1]-yr)

我们需要宽度和高度以及顶部左侧的坐标用于绘制矩形。self.td 元组提供左上角,xr*2 提供宽度,yr*2 提供高度。

形状在小工具画布上绘制。我们随机选择一种颜色用于绘制。按下的按钮的文本属性为我们提供要绘制的形状 −

color = (random(), random(), random())
with self.w.canvas:
   Color(*color)
   if self.btn=='Rectangle':
      Rectangle(pos=self.td, size=(xr*2,yr*2))
   if self.btn=='Circle':
      Ellipse(pos=(c), size=(xr,yr))

三个切换按钮绑定至一个方法。如果标题为 Clear,则小工具画布将被清除。

def clear_canvas(self, instance, value):
   self.btn = instance.text
   self.press = True
   if value == 'down' and self.btn == 'Clear':
      self.w.canvas.clear()
   return True

Example

应用程序的 complete code 如下 −

from random import random
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.graphics import Color, Ellipse, Line, Rectangle
from kivy.uix.togglebutton import ToggleButton
from kivy.uix.boxlayout import BoxLayout
from kivy.core.window import Window

Window.size = (720, 400)

class MyPaintApp(App):
   def clear_canvas(self, instance, value):
      self.btn = instance.text
      self.press = True
      if value == 'down' and self.btn == 'Clear':
         self.w.canvas.clear()
      return True

   def on_touch_down(self, *args):
      self.td = args[1].pos

   def on_touch_up(self, *args):
      if self.press == True:
         self.press = False
         return True
      self.tu = args[1].pos
      xr = (self.tu[0] - self.td[0]) / 2
      yr = (self.td[1] - self.tu[1]) / 2
      c = (self.td[0] + xr, self.td[1] - yr)
      color = (random(), random(), random())
      with self.w.canvas:
         Color(*color)
         if self.btn == 'Rectangle':
            Rectangle(pos=self.td, size=(xr * 2, yr * 2))
         if self.btn == 'Circle':
            Ellipse(pos=(c), size=(xr, yr))

   def build(self):
      self.press = False
      self.btn = 'Rectangle'

      lo = BoxLayout(orientation='vertical')

      self.w = Widget()
      self.w.bind(on_touch_down=self.on_touch_down)
      self.w.bind(on_touch_up=self.on_touch_up)
      lo.add_widget(self.w)

      hlo = BoxLayout(orientation='horizontal', size_hint=(1, .1))

      self.b2 = ToggleButton(text='Circle', group='mode')
      self.b1 = ToggleButton(text='Rectangle', state='down', group='mode')
      self.b3 = ToggleButton(text='Clear', group='mode')
      self.b1.bind(state=self.clear_canvas)
      self.b2.bind(state=self.clear_canvas)
      self.b3.bind(state=self.clear_canvas)

      hlo.add_widget(self.b1)
      hlo.add_widget(self.b2)
      hlo.add_widget(self.b3)
      lo.add_widget(hlo)

      return lo

MyPaintApp().run()

Output

运行以上代码。选择你想绘制的形状。将鼠标从左上拖到右下。矩形/圆形将在不同位置以随机颜色绘制。

kivy drawing app

单击 Clear 按钮可清除画布上的图纸。