如何在Kivy中从数组更新纹理?

时间:2019-03-11 10:10:22

标签: python kivy kivy-language

我是Kivy的新手,但是已经看了教程。我想要一个包含从数组生成的纹理或图像的小部件,该纹理或图像在每一帧都会改变。请参阅下面的内容。当我调整窗口大小时,当前行为是错误的-我认为旧的Rectangle永远不会被删除,但是我看不到该怎么做。它还在主窗口左下方的默认(100,100)视图中显示同一图像。我需要更改什么以实现所需的行为,并且在调整窗口大小时不会出现伪影?

from kivy.app import App
from kivy.properties import ObjectProperty
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.layout import Layout
from kivy.graphics import Rectangle
from kivy.graphics.texture import Texture
from kivy.clock import Clock
import numpy as np
import random


class MainDisplay(Layout):
    tex = ObjectProperty(None)

    def __init__(self, **kwargs):
        super(MainDisplay, self).__init__(**kwargs)
        Clock.schedule_once(self.texture_init, 0)

    def texture_init(self, instance):
        self.tex = Texture.create()

    def update(self, dt):
        size = 64 * 64 * 3
        buf = np.array([int(random.random() * x * 255 / size) for x in range(size)])

        print('update', max(buf), min(buf), np.mean(buf))
        # then blit the buffer
        self.tex.blit_buffer(buf.tostring(), colorfmt='bgr', bufferfmt='ubyte')
        print('end update')

        print(self.canvas)
        print(self.size, self.pos, self, self.parent)
        with self.canvas:
            Rectangle(texture=self.tex, size=(self.width / 2, self.height / 2), pos=(self.center_x / 2, self.center_y / 2))


class MainWindow(BoxLayout):
    md = ObjectProperty(None)

    def __init__(self, **kwargs):
        super(MainWindow, self).__init__(**kwargs)

    def update(self, dt):
        self.md.update(dt)


class ProtoApp(App):
    def build(self):
        mainWindow = MainWindow()

        Clock.schedule_interval(mainWindow.update, 1.0/10.0)
        return mainWindow


if __name__ == "__main__":
    ProtoApp().run()

带有proto.kv文件:

<MainWindow>:
    md: md
    MainDisplay:
        id: md
        size_hint: (0.5, 0.5)

在此先感谢您的帮助!

1 个答案:

答案 0 :(得分:1)

问题

每当调整窗口大小时,它就会创建一个新的矩形并留下前一个矩形的痕迹。

解决方案

使用画布的内置功能clear()

摘要

def update(self, dt):
    size = 64 * 64 * 3
    buf = np.array([int(random.random() * x * 255 / size) for x in range(size)])

    # then blit the buffer
    self.tex.blit_buffer(buf.tostring(), colorfmt='bgr', bufferfmt='ubyte')

    with self.canvas:
        self.rect = Rectangle(texture=self.tex, size=(self.width / 2, self.height / 2),
                              pos=(self.center_x / 2, self.center_y / 2))

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

def update_rect(self, *args):
    self.canvas.clear()
    self.rect.pos = self.pos
    self.rect.size = self.size