Как обновить текстуру из массива в Kivy? - PullRequest
0 голосов
/ 11 марта 2019

Я новичок в Kivy, но посмотрел уроки.Я хочу иметь виджет, содержащий текстуру или изображение, сгенерированное из массива, который будет меняться в каждом кадре.Смотрите ниже, что я имею в настоящее время.Текущее поведение неверно, когда я изменяю размер окна - я думаю, что старый прямоугольник никогда не удаляется, но я не вижу, как это сделать.Он также показывает то же изображение в виде по умолчанию (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 Ответ

1 голос
/ 11 марта 2019

Проблема

При изменении размера окна создается новый прямоугольник и остаются следы предыдущего.

Решение

Используйте встроенную функцию холста,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
...