如何在python中引用Kivy Canvas

问题描述 投票:0回答:2

如果UI是用kv构建的,我如何引用Kivy Canvas从python文件中绘图,例如这里是我的.py:

# canvasCallApp.py...

from kivy.app import App

class canvasCallApp(App):
    pass

if __name__ == '__main__':
    canvasCallApp().run()

而我的.kv:

# canvasCallApp.kv...

BoxLayout:
    id: left_box
    canvas:
        Color:
            rgb: 0.6, 0.6, 0.6
        Rectangle:
            pos: self.pos
            size: self.size
    Widget:
        size_hint_x: None
        width: left_box.width - right_box.width        
    BoxLayout:
        width: 200
        id: right_box
        Button:
            text: 'I ma a button'

哪个产生:

enter image description here

如何从left_box获取画布以便从python中进行绘制?无法从文档中找到答案。

python user-interface kivy kivy-language
2个回答
0
投票

我选择放弃单独的kivy语言并在python中完成所有操作,这需要一些小部件嵌套来实现正确的布局,更重要的是创建,绑定和初始化我们稍后可以引用的小部件/画布对象:


# canvasTest.py...

from kivy.app import App
from kivy.graphics import Rectangle
from kivy.graphics import Color
from kivy.uix.widget import Widget
from kivy.uix.button import Button
from kivy.uix.boxlayout import BoxLayout
from random import random as r


class rootCanvas(Widget):
    def __init__(self, **kwargs):
        super(rootCanvas, self).__init__(**kwargs)
        with self.canvas:
            Color(r(), 1, 1, mode='hsv')
            self.rect = Rectangle(pos=self.pos, size=self.size)

        self.bind(pos=self.update_rect)
        self.bind(size=self.update_rect)

    def update_rect(self, *args):
        self.rect.pos = self.pos
        self.rect.size = (self.size[0], self.size[1])

    def change_color(self, *args):
        with self.canvas:
            Color(r(), 1, 1, mode='hsv')
            self.rect = Rectangle(pos=self.pos, size=self.size)


class canvasTest(App):
    def build(self):
        root = BoxLayout()
        sideBar = BoxLayout(size=(200, 100), size_hint=(None, 1))
        widget = rootCanvas()
        root.add_widget(widget)
        btn_1 = Button(
            text='Change Canvas Color',
            width=200,
            on_press=widget.change_color)
        sideBar.add_widget(btn_1)
        root.add_widget(sideBar)
        return root


if __name__ == '__main__':
    canvasTest().run()




结果是:

enter image description here


-1
投票

如果您愿意动态更改画布的颜色或大小,

我建议使用Kivy Properties。

这是代码。

from kivy.properties import ListProperty
from kivy.lang import Builder
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout


class RootLayout(BoxLayout):
    canvas_color = ListProperty([0, 1, 1])


class canvasCallApp(App):
    def build(self):
        return kv


kv = Builder.load_string('''
RootLayout:
    id: left_box
    canvas:
        Color:
            rgb: root.canvas_color
        Rectangle:
            pos: self.pos
            size: self.size
    Widget:
        size_hint_x: None
        width: left_box.width - right_box.width        
    BoxLayout:
        width: 200
        id: right_box
        Button:
            text: 'I ma a button'
''')


if __name__ == '__main__':
    canvasCallApp().run()

我还建议使用RootLayout,这样可以更容易地通过root.variable_name从python代码引用变量。

如果要更改画布的背景,还可以将kivy代码更改为

canvas:
    Color:
        rgb: root.canvas_color
    Rectangle:
        pos: self.pos
        size: self.size
        source: root.image_path

通过这种方式,您可以从StringProperty导入kivy.properties并应用相同的东西。随着image_path的值发生变化,背景会自动更改。

如果要直接访问画布以重绘画布,可以使用with canvas

from kivy.uix.boxlayout import BoxLayout
from kivy.graphics import Rectangle, Color

class SomeBoxLayout(BoxLayout)
    def __init__(self, **kwargs):
        super(SomeBoxLayout, self).__init__(**kwargs)

        with self.canvas:
            Color(1, 0, 0, 1)  # set the color to red
            self.rect = Rectangle(pos=self.center,
                                  size=(self.width/2.,
                                        self.height/2.))

    def redraw(self):
        self.canvas.clear()
        with self.canvas:
            Color(0, 0, 1, 1)  # set the color to blue
            self.rect = Rectangle(pos=self.center,
                                  size=(self.width/2.,
                                        self.height/2.))

请注意,在再次绘制内容之前,您应该执行canvas.clear()

另外,你可以用这种方式使用with self.canvas.beforewith self.canvas.after

© www.soinside.com 2019 - 2024. All rights reserved.