Kivy - 繪製圓形



本章我們將動態地在 Kivy 應用視窗上繪製一個圓形。其思路是使用四個 Kivy 滑塊元件設定圓形的寬度、高度和中心點值,並在箱式佈局畫布上重新整理大小和位置。

“kivy.graphics” 模組包含 Ellipse 類。圓形實際上是寬度和高度相等的橢圓。

語法

在任何元件的畫布上繪製橢圓的語法如下:

with widget.canvas:
   Color(1, 1, 1)
   Ellipse(
      pos=(w, h), size=(cx, cy),
      angle_start=0, angle_end=360
)

使用滑塊來選擇“w”、“h”、“cx”和“cy”的值。我們應用視窗的預期外觀如下:

Kivy Circle Drawing

主佈局使用垂直箱式佈局。它包含兩個水平箱式佈局,每個都包含兩個滑塊和兩個標籤。在第一個中放置寬度和高度選擇器;在第二個中,可以選擇橢圓的 X 和 Y 座標。然後,頂部垂直箱式佈局新增一個 FloatLayout,其畫布是繪圖的目標。

以下“kv”檔案組裝了上述元件結構。

示例

BoxLayout:
   orientation: 'vertical'
   BoxLayout:
      size_hint_y: None
      height: sp(50)
      BoxLayout:
         orientation: 'horizontal'
         Slider:
            id: wd
            min: 100
            max: 300
            value: 200
         Label:
            text: 'Width: {}'.format(int(wd.value))
         Slider:
            id: ht
            min: 100
            max: 300
            value: 200
         Label:
            text: 'Height: {}'.format(int(ht.value))
   BoxLayout:
      size_hint_y: None
      height: sp(50)
      BoxLayout:
         orientation: 'horizontal'
         Slider:
            id: cx
            min: 10
            max: 600
            value: 360
         Label:
            text: 'cx: {}'.format(int(cx.value))
         Slider:
            id: cy
            min: 10
            max: 300
            value: 50
         Label:
            text: 'cy: {}'.format(int(cy.value))

   FloatLayout:
      canvas:
         Color:
            rgb: 1, 1, 1
         Ellipse:
            pos: cx.value, cy.value
            size: wd.value, ht.value
            angle_start: 0
            angle_end: 360

您只需要在我們的 Kivy 應用程式碼中載入此“kv”檔案即可。在 build() 方法內部呼叫“kivy.lang.Builder”類的 load_file() 方法。

from kivy.app import App
from kivy.lang import Builder
from kivy.core.window import Window

Window.size = (720,400)
class CircleApp(App):
   def build(self):
      return Builder.load_file('circledemo.kv')
   
CircleApp().run()

就是這樣。執行程式,您將看到在起始位置繪製的圓形。滑動控制元件以獲得不同的值,並檢視圓形如何改變其位置和大小。

如果您希望使用純 Python 程式碼來組合應用程式視窗外觀,您可以手動將所需的元件放置在 build() 方法中,如下所示:

def build(self):
   # main layout
   lo = BoxLayout(orientation='vertical', size=Window.size)
   
   # for width and height sliders
   sliders_wh = BoxLayout(size_hint_y=None, height=50)

   slb1 = BoxLayout(orientation='horizontal')
   self.sl1 = Slider(min=100, max=300, value=200)
   l1 = Label(text='Width: {}'.format(int(self.sl1.value)))
   slb1.add_widget(self.sl1)
   slb1.add_widget(l1)
   self.sl2 = Slider(min=100, max=300, value=200)
   l2 = Label(text='Height: {}'.format(int(self.sl2.value)))
   slb1.add_widget(self.sl2)
   slb1.add_widget(l2)
   sliders_wh.add_widget(slb1)
   
   # for cx and cy sliders
   sliders_xy = BoxLayout(size_hint_y=None, height=50)
   slb2 = BoxLayout(orientation='horizontal')
   self.sl3 = Slider(min=10, max=600, value=360)
   l3 = Label(text='cx: {}'.format(int(self.sl3.value)))
   slb2.add_widget(self.sl3)
   slb2.add_widget(l3)
   self.sl4 = Slider(min=10, max=300, value=50)
   l4 = Label(text='cy: {}'.format(int(self.sl4.value)))
   slb2.add_widget(self.sl4)
   slb2.add_widget(l4)
   sliders_xy.add_widget(slb2)
   
   lo.add_widget(sliders_wh)
   lo.add_widget(sliders_xy)
   
   self.flo = FloatLayout() # circle canvas
   
   lo.add_widget(self.flo)
   
   # redraw cicle
   self.ev = Clock.schedule_interval(self.callback, .3)
   return lo

但是,為了持續重新整理畫布上圓形的大小和位置,我們需要安排一個週期性事件,清除畫布以擦除現有圓形,並使用寬度、高度、cx 和 cy 的瞬時值重新繪製它。

必須在 App 類中新增以下回調方法:

def callback(self, dt):
   self.flo.canvas.clear()
   with self.flo.canvas:
      Color(1, 1, 1)
      Ellipse(
         pos=(self.sl3.value, self.sl4.value),
         size=(self.sl1.value, self.sl2.value),
         angle_start=0, angle_end=360
      )

現在您可以執行程式碼了。將獲得與“kv”檔案版本完全相同的結果。

廣告
© . All rights reserved.