Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/284.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_Multithreading_Kivy - Fatal编程技术网

Python 线程问题使用线程时Kivy图像纹理未更新

Python 线程问题使用线程时Kivy图像纹理未更新,python,multithreading,kivy,Python,Multithreading,Kivy,我正在尝试使用Kivy制作一个使用线程的应用程序。背景线程更新图像小部件主类中的纹理 问题是纹理变量会被更新,但不会显示在kivy Gui应用程序中 这是密码 我使用了ObjectProperty触发了标签:文本和图像:纹理的更新,但只有标签:文本真正得到了更新 import random import threading from kivy.app import App from kivy.core.image import Texture from kivy.lang import B

我正在尝试使用Kivy制作一个使用线程的应用程序。背景线程更新图像小部件主类中的纹理

问题是纹理变量会被更新,但不会显示在kivy Gui应用程序中

这是密码 我使用了ObjectProperty触发了标签:文本和图像:纹理的更新,但只有标签:文本真正得到了更新

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()
随机导入
导入线程
从kivy.app导入应用程序
从kivy.core.image导入纹理
从kivy.lang导入生成器
从kivy.properties导入NumericProperty、ObjectProperty
从kivy.uix.widget导入widget
Builder.load_字符串(“”)
:
btn1:btn1
label1:label1
img1:img1
网格布局:
科尔斯:1
尺寸:根。宽度,根。高度
按钮:
文字:“你好”
id:btn1
发布时:root.btn()
标签:
id:label1
文字:“你好”
图片:
id:img1
''')
类主(小部件):
btn1=对象属性(无)
label1=ObjectProperty(无)
img1=ObjectProperty(无)
a=对象属性(1)
newtexture=ObjectProperty(2)
更新=错误
iter=1
def btn(自身):
self.update=非self.update
t1=threading.Thread(目标=self.updateValue)
t1.start()
#self.updateValue()
def更新值(自身):
while(self.update):
自我评价a+=2
testexture=Texture.create(大小=(512),colorfmt='rgb')
尺寸=512*512*3
如果self.iter==1:
buf=[int(x%128)表示范围内的x(大小)]
self.iter=0
#打印(“条状”)
其他:
buf=[int(x%256)表示范围内的x(大小)]
self.iter=1
#打印(“随机”)
buf=字节数组(buf)
testexture.blit_缓冲区(buf,colorfmt='rgb',bufferfmt='ubyte')
self.newtexture=testexture
#打印(“生成”)
_a上的定义(自身、实例、值):
打印('我的属性a更改为',值)
self.label1.text=str(值)
新文本上的定义(自身、实例、值):
self.img1.texture=值
self.img1.canvas.ask_update()
打印(“更新的纹理”)
打印(值)
MaainApp类(应用程序):
def生成(自):
返回主管道()
MaainApp().run()
另一件事是,如果在更新和线程中删除While循环,只需使用按钮触发,它就可以正常工作。但这对我的应用程序来说毫无用处

请任何人告诉我到底发生了什么,我如何使用线程更新图像纹理


谢谢

我一直被我认为与您遇到的问题相同的问题所困扰。我相信您知道,对GUI的更改必须在主线程上进行。_a()上的
和_newtexture()上的
将始终在主线程上运行,因此在该区域似乎一切正常。然而,
Texture
类处理
OpenGL
纹理,我相信这会对使用
Texture
blit\u buffer()
方法施加相同的约束。下面是您的
Main
Widget
的一个修改版本,它适用于我,使用
Clock.schedule\u once()
将对
blit\u 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)