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"的值。我们的应用程序窗口的预期外观如下 −
主布局使用垂直框布局。它包括两个水平框,每个框包含两个滑块和两个标签。在第一个框中放置宽度和高度选择器;在第二个框中,可以选择椭圆的 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 App 代码中加载这个"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"文件版本完全相同的结果。