线程问题 当使用线程时,Kivy图像纹理不更新。

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

我正试图用Kivy制作一个使用线程的应用程序。后台线程更新Image Widget主类中的纹理,问题是纹理变量被更新,但在kivy Gui应用中却没有显示。

问题是纹理变量被更新了,但在kivy Gui应用程序中却没有显示出来。

以下是我使用的代码 对象属性 同时触发更新 标签:文本图片:纹理 但是,只有 标签:文本 日新月异

import random
import threading

from kivy.app import App

from kivy.core.image import Texture

from kivy.lang import Builder
from kivy.properties import NumericProperty, ObjectProperty
from kivy.uix.widget import Widget

Builder.load_string('''
<Main>:

    btn1:btn1
    label1:label1
    img1:img1
    GridLayout:
        cols:1
        size:root.width,root.height
        Button:
            text:"Hello"
            id:btn1
            on_release:root.btn()

        Label:
            id:label1
            text:"hello"
        Image:
            id:img1

''')


class Main(Widget):
    btn1 = ObjectProperty(None)
    label1 = ObjectProperty(None)
    img1 = ObjectProperty(None)
    a = ObjectProperty(1)
    newtexture = ObjectProperty(2)



    update = False
    iter = 1

    def btn(self):
        self.update = not self.update
        t1 = threading.Thread(target=self.updateValue)
        t1.start()
        # self.updateValue()

    def updateValue(self):
        while (self.update):
            self.a += 2

            testexture = Texture.create(size=(512, 512), colorfmt='rgb')
            size = 512 * 512 * 3

            if self.iter == 1:
                buf = [int(x % 128) for x in range(size)]
                self.iter = 0
                # print("strip")
            else:
                buf = [int(x % 256) for x in range(size)]
                self.iter = 1
                # print("random")

            buf = bytearray(buf)
            testexture.blit_buffer(buf, colorfmt='rgb', bufferfmt='ubyte')
            self.newtexture = testexture
            # print("Generated")

    def on_a(self, instance, value):
        print('My property a changed to', value)
        self.label1.text = str(value)

    def on_newtexture(self, instance, value):
        self.img1.texture = value
        self.img1.canvas.ask_update()
        print("updated texture")
        print(value)

class MaainApp(App):
    def build(self):
        return Main()


MaainApp().run()

另一件事,如果你删除更新和线程中的while循环,并只是触发触发按钮,它的工作完全正常。但是,这是对我的应用程序没有用的我

请有谁能告诉我到底发生了什么,我怎么能用线程更新图像纹理。

谢谢你

python multithreading kivy
1个回答
2
投票

我已经被我认为和你遇到的相同的问题所困扰了。我相信你也知道,对GUI的修改必须在主线程上进行。你的 on_a()on_newtexture() 将始终在主线程上运行,因此在该领域似乎一切正常。然而,在主线程上运行的 Texture 类处理 OpenGL 纹理,我相信这也会对使用 blit_buffer() 方式 Texture. 所以这里有一个修改版的你的 Main Widget 这对我来说,使用 Clock.schedule_once() 呼叫 blit_buffer() 回到主线上。

class Main(Widget):
    btn1 = ObjectProperty(None)
    label1 = ObjectProperty(None)
    img1 = ObjectProperty(None)
    a = ObjectProperty(1)
    newtexture = ObjectProperty(2)

    update = False
    iter = 1

    def btn(self):
        self.update = not self.update
        t1 = threading.Thread(target=self.updateValue, daemon=True)
        t1.start()
        # self.updateValue()

    def updateValue(self):
        while (self.update):
            self.a += 2

            testexture = Texture.create(size=(512, 512), colorfmt='rgb')
            size = 512 * 512 * 3

            if self.iter == 1:
                buf = [int(x % 128) for x in range(size)]
                self.iter = 0
                # print("strip")
            else:
                buf = [int(x % 256) for x in range(size)]
                self.iter = 1
                # print("random")

            buf = bytearray(buf)
            Clock.schedule_once(partial(self.updateTexture, testexture, buf))
            # print("Generated")

    def updateTexture(self, testexture, buf, *args):
        testexture.blit_buffer(buf, colorfmt='rgb', bufferfmt='ubyte')
        self.newtexture = testexture

    def on_a(self, instance, value):
        print('My property a changed to', value)
        self.label1.text = str(value)

    def on_newtexture(self, instance, value):
        self.img1.texture = value
        self.img1.canvas.ask_update()
        print("updated texture")
        print(value)
© www.soinside.com 2019 - 2024. All rights reserved.