Kivy 简明教程
Kivy - Circle Drawing
在本章中,我们将在 Kivy 应用程序窗口中动态绘制一个圆。这个想法是用四个 Kivy 滑块控件来设置圆的宽度、高度和中心点,以及在框布局画布中刷新大小和位置。
“kivy.graphics”模块包括 Ellipse 类。实际上,一个圆是一个等宽高的椭圆。
Syntax
在任何控件的画布上绘制椭圆的语法如下 −
with widget.canvas:
Color(1, 1, 1)
Ellipse(
pos=(w, h), size=(cx, cy),
angle_start=0, angle_end=360
)
滑块用于选择“w”、“h”、“cx”和“cy”的值。我们的应用程序窗口的预期外观如下 −
主布局使用垂直框布局。它包括两个水平框,每个框包含两个滑块和两个标签。在第一个框中放置宽度和高度选择器;在第二个框中可以选取椭圆的 X 和 Y 坐标。然后,顶部垂直框添加一个 FloatLayout,其画布是绘图目标。
以下“kv”文件组装了上述控件结构。
Example
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
您需要做的就是将这个“kv”文件加载到我们的 Kivy 应用程序代码中。在 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”文件版本完全相同。