Kivy - 畫布



與其他一些GUI工具包(例如TKinter)不同,Kivy沒有獨立的Canvas小部件。相反,您需要使用Kivy中每個小部件預設已有的畫布。建立小部件時,您可以建立在畫布上繪圖所需的所有指令。

需要注意的是,所有小部件都有不同的畫布,但所有畫布都在完全相同的繪圖空間(即座標空間)中繪製。此外,繪圖空間不限於小部件的位置和大小。(0,0)點始終是繪圖空間的左下角。

"canvas.before"屬性在需要操作例項顏色時特別有用。另一方面,canvas.after用於在新增子項後執行任何指令。它在遍歷所有子項後呼叫。

Kivy中的畫布是一組繪圖指令。要繪圖,您需要一個Canvas物件和Instruction物件。例如,要在標籤的畫布上繪製矩形:

from kivy.graphics import *
with label.canvas:
   Color(1., 0, 0)    # Add a red color

   # Add a rectangle
   Rectangle(pos=(10, 10), size=(500, 500))

如果您不使用Python的上下文管理器,則必須這樣做:

label.canvas.add(Color(1., 0, 0))
label.canvas.add(Rectangle(size=(500, 500)))

您可以在任何小部件的畫布上繪製矩形、橢圓、直線和貝塞爾曲線,包括Widget物件本身。(Widget類是Kivy中所有其他可視小部件的基礎)

要在畫布上繪製矩形,我們需要指定pos和size屬性:

from kivy.graphics import Rectangle
Rectangle(**kwargs)

引數

  • pos - 指定矩形位置的X和Y座標值列表,格式為(x, y)。

  • size - 指定矩形寬度和高度的列表,格式為(width, height)。

以下程式碼在Widget物件的畫布上繪製一個矩形:

widget=Widget()

with widget.canvas:
   Color(0,0,1,1)
   Rectangle(pos=(50,300), size_hint=(None, None), size=(300,200))

ColorRectangle指令會自動新增到畫布物件中,並在繪製視窗時使用。

語法

您可能想使用“kv”語言語法:

Widget:
   canvas:
      color:
         rgb: 0,0,1
      Rectangle:
         pos: self.pos
         size: self.size

Kivy中的Label物件沒有背景顏色屬性。要解決此問題,您可以在其畫布上繪製一個填充所需顏色的矩形來作為背景。

lbl = Label(text='Hello World', font_size=24)
   with lbl.canvas.before:
      Color(1,1,0)
      Rectangle(pos=lbl.pos, size=lbl.size)

或者,使用“kv”指令碼:

Label:
   text:'Hello World'
   font_size:24
   canvas.before:
      Color:
         rgb: (1,1,0)
      Rectangle:
         pos:self.pos
         size=:self.size

語法

您可以使用以下語法在畫布上繪製橢圓:

from kivy.graphics import Ellipse
Ellipse(*args, **kwargs)

引數

  • segments - 定義繪製橢圓所需的線段數。線段越多,如果線段很多,繪製會越平滑。

  • angle_start - 浮點數,預設為0.0,指定磁碟部分的起始角度(度)。

  • angle_end - 浮點數,預設為360.0,指定磁碟部分的結束角度(度)。

  • angle_end - 橢圓的結束角度(度),預設為360。

  • angle_start - 橢圓的起始角度(度),預設為0。

  • pos - 畫布座標系中的位置

  • size - 橢圓的X和Y半徑。如果兩者相等,則成為圓。

您還可以透過將影像檔案指定為矩形或橢圓的source屬性,直接在畫布上繪製圖像。

示例 1

以下程式碼實現了上面解釋的所有繪圖指令,以在小部件畫布上顯示矩形、橢圓和影像。它還在其畫布上繪製了具有背景顏色的矩形的標籤。

from kivy.app import App
from kivy.uix.image import Image
from kivy.uix.widget import Widget
from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.graphics import *
from kivy.core.window import Window

Window.size = (720,400)

class canvasdemoapp(App):
   def build(self):
      widget=Widget()

      # rectangle on canvas
      with widget.canvas:
         Color(0,0,1,1)
         Rectangle(
            pos=(50,300), size_hint=(None, None),
            size=(300,200)
         )
         Color(0.5, .2, 0.4, 1)
         d = 100

         # ellipse
         Ellipse(pos=(600,100), size=(d+75, d))
         Color(.5,.5,.5)

         # image
         Rectangle(source='kivy-logo.png', pos=(50,100))
         Color(1,1,1)
         Rectangle(source='TPlogo.png', pos=(300, 100))

         # label with background
         lbl = Label(
            text='Hello World', font_size=24,
            pos=(Window.width/2, 300), size =(200,200),
            color=(0,0,1,1)
         )
         with lbl.canvas.before:
            Color(1,1,0)
            Rectangle(pos=lbl.pos, size=lbl.size)
         widget.add_widget(lbl)
         btn=Button(
            text='Button', font_size=24,
            background_color= (.8, .4, .3, 1),
            pos=(500,10)
         )
         widget.add_widget(btn)
      return widget
canvasdemoapp().run()

輸出

執行此程式碼時,將產生以下輸出:

Kivy Canvas

示例 2

Widget物件響應所有觸控事件(例如on_touch_down和on_touch_move等)。

在下面的示例中,Widget物件的on_touch_down事件上的回撥獲取觸控事件發生處的座標,並使用RGB顏色的隨機值繪製圓(X和Y半徑相等的橢圓)。

from kivy.app import App
from kivy.uix.widget import Widget
from kivy.graphics import *
import random
from kivy.core.window import Window

Window.size = (720,300)
class widget(Widget):
   def on_touch_down(self, touch):
      colorR = random.randint(0, 255)
      colorG = random.randint(0, 255)
      colorB = random.randint(0, 255)
   
      self.canvas.add(Color(
         rgb=(colorR / 255.0, colorG / 255.0, colorB / 255.0)
      ))
   
      d = 30
      self.canvas.add(Ellipse(
         pos=(touch.x - d / 2, touch.y - d / 2),
         size=(d, d)
      ))
      
class circlesapp(App):
   def build(self):
      return widget()
circlesapp().run()

輸出

執行程式並在不同位置生成touch_down事件。圓圈將繪製在相應位置。

Kivy Canvas Circle
廣告