Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/305.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在python中引用Kivy画布_Python_User Interface_Kivy_Kivy Language - Fatal编程技术网

如何在python中引用Kivy画布

如何在python中引用Kivy画布,python,user-interface,kivy,kivy-language,Python,User Interface,Kivy,Kivy Language,如果UI是在kv中构建的,我将如何引用Kivy画布来从python文件进行绘制,例如,下面是my.py: # canvasCallApp.py... from kivy.app import App class canvasCallApp(App): pass if __name__ == '__main__': canvasCallApp().run() 和我的.kv: # canvasCallApp.kv... BoxLayout: id: left_bo

如果UI是在kv中构建的,我将如何引用Kivy画布来从python文件进行绘制,例如,下面是my.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'

产生:


为了从python中绘图,我如何到达
左框中的画布?无法从文档中找到它。

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

我建议使用Kivy属性

这是代码

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\u name
从python代码中引用变量

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

canvas:
    Color:
        rgb: root.canvas_color
    Rectangle:
        pos: self.pos
        size: self.size
        source: root.image_path
通过这种方式,您可以从
kivy.properties
导入
StringProperty
,并应用相同的内容。当
image\u path
的值改变时,背景会自动改变

如果要直接访问画布以重新绘制画布,可以将
与画布一起使用

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()


另外,你可以在self.canvas中使用
,在self.canvas中使用
之前或
之后,用这种方式使用

我选择放弃单独的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()




结果:


谢谢,但我的目标是触发动画,所以不确定属性是否会剪切动画,我想的是类似于
self.widget.canvas.clear()
的东西,但到目前为止运气不好。@基诺我添加了更多的代码并做了一些解释。过来看!我也更喜欢用代码做事情,但从
.kv
声明转换可能会很棘手,因为文档往往只使用
.kv
。你如何进行转换?尝试和错误,或者是否有更面向程序的文档/教程?