gpt4 book ai didi

python - 从另一个线程更改 kivy 属性

转载 作者:太空狗 更新时间:2023-10-30 00:50:26 25 4
gpt4 key购买 nike

我正在试验一些 kivy 代码。我尝试修改一个 kivy 属性 (text_colour) 从线程库创建的胎面。程序运行正常,但线程不会更改属性。

我还尝试在类中创建一个方法,将值作为参数获取,但也失败了。

from kivy.app import App

from kivy.uix.boxlayout import BoxLayout
from kivy.properties import ListProperty


import threading
import random
import time


def zaaa():
import time
time.sleep(3)
ScatterTextWidget.text_colour = [0, 0, 1, 1]
print "function ran"

t = threading.Thread(target= zaaa)
t.start()


class ScatterTextWidget(BoxLayout):

text_colour = ListProperty([1, 0, 0, 1])

def change_label_colour(self, *args):
colour = [random.random() for i in xrange(3)] + [1]
self.text_colour = colour

def press(self, *args):
self.text_colour = [1, 1, 1, 1]


class TataApp(App):
def build(self):
return ScatterTextWidget()


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

输出:

[INFO              ] Kivy v1.8.0
[INFO ] [Logger ] Record log in /home/mbp/.kivy/logs/kivy_14-02-26_44.txt
[INFO ] [Factory ] 157 symbols loaded
[DEBUG ] [Cache ] register <kv.lang> with limit=None, timeout=Nones
[DEBUG ] [Cache ] register <kv.image> with limit=None, timeout=60s
[DEBUG ] [Cache ] register <kv.atlas> with limit=None, timeout=Nones
[INFO ] [Image ] Providers: img_tex, img_dds, img_pygame, img_pil, img_gif
[DEBUG ] [Cache ] register <kv.texture> with limit=1000, timeout=60s
[DEBUG ] [Cache ] register <kv.shader> with limit=1000, timeout=3600s
[DEBUG ] [App ] Loading kv </home/mbp/workspace/KiviPlay/tata.kv>
[DEBUG ] [Window ] Ignored <egl_rpi> (import error)
[INFO ] [Window ] Provider: pygame(['window_egl_rpi'] ignored)
libpng warning: iCCP: known incorrect sRGB profile
[DEBUG ] [Window ] Display driver x11
[DEBUG ] [Window ] Actual window size: 800x600
[DEBUG ] [Window ] Actual color bits r8 g8 b8 a8
[DEBUG ] [Window ] Actual depth bits: 24
[DEBUG ] [Window ] Actual stencil bits: 8
[DEBUG ] [Window ] Actual multisampling samples: 2
[INFO ] [GL ] OpenGL version <4.3.12618 Compatibility Profile Context 13.251>
[INFO ] [GL ] OpenGL vendor <ATI Technologies Inc.>
[INFO ] [GL ] OpenGL renderer <AMD Radeon HD 7700 Series>
[INFO ] [GL ] OpenGL parsed version: 4, 3
[INFO ] [GL ] Shading version <4.30>
[INFO ] [GL ] Texture max size <16384>
[INFO ] [GL ] Texture max units <32>
[DEBUG ] [Shader ] Fragment compiled successfully
[DEBUG ] [Shader ] Vertex compiled successfully
[DEBUG ] [ImagePygame ] Load </usr/lib/python2.7/site-packages/Kivy-1.8.0-py2.7-linux-x86_64.egg/kivy/data/glsl/default.png>
[INFO ] [Window ] virtual keyboard not allowed, single mode, not docked
[INFO ] [Text ] Provider: pygame
[DEBUG ] [Cache ] register <kv.loader> with limit=500, timeout=60s
[INFO ] [Loader ] using a thread pool of 2 workers
[DEBUG ] [Cache ] register <textinput.label> with limit=None, timeout=60.0s
[DEBUG ] [Cache ] register <textinput.width> with limit=None, timeout=60.0s
[DEBUG ] [Atlas ] Load </usr/lib/python2.7/site-packages/Kivy-1.8.0-py2.7-linux-x86_64.egg/kivy/data/../data/images/defaulttheme.atlas>
[DEBUG ] [Atlas ] Need to load 1 images
[DEBUG ] [Atlas ] Load </usr/lib/python2.7/site-packages/Kivy-1.8.0-py2.7-linux-x86_64.egg/kivy/data/../data/images/defaulttheme-0.png>
[DEBUG ] [ImagePygame ] Load </usr/lib/python2.7/site-packages/Kivy-1.8.0-py2.7-linux-x86_64.egg/kivy/data/../data/images/defaulttheme-0.png>
[INFO ] [GL ] NPOT texture support is available
[INFO ] [OSC ] using <multiprocessing> for socket
[DEBUG ] [Base ] Create provider from mouse
[DEBUG ] [Base ] Create provider from probesysfs
[DEBUG ] [ProbeSysfs ] using probsysfs!
[INFO ] [Base ] Start application main loop
<kivy.properties.ListProperty object at 0x124f870>
function ran
[INFO ] [Base ] Leaving application in progress...

最佳答案

您不能修改 kivy 属性或从外部线程执行任何与 OpenGL 相关的工作。

解决方案是调度callbacks使用 kivy 的时钟,它将从 kivy 的主线程调用一个函数并为您完成工作。

就个人而言,当我使用第二个线程时,我使用一个线程间通信队列,如下所示:

from Queue import Queue

class KivyQueue(Queue):
'''
A Multithread safe class that calls a callback whenever an item is added
to the queue. Instead of having to poll or wait, you could wait to get
notified of additions.

>>> def callabck():
... print('Added')
>>> q = KivyQueue(notify_func=callabck)
>>> q.put('test', 55)
Added
>>> q.get()
('test', 55)

:param notify_func: The function to call when adding to the queue
'''

notify_func = None

def __init__(self, notify_func, **kwargs):
Queue.__init__(self, **kwargs)
self.notify_func = notify_func

def put(self, key, val):
'''
Adds a (key, value) tuple to the queue and calls the callback function.
'''
Queue.put(self, (key, val), False)
self.notify_func()

def get(self):
'''
Returns the next items in the queue, if non-empty, otherwise a
:py:attr:`Queue.Empty` exception is raised.
'''
return Queue.get(self, False)

第二个线程使用 put 把东西放到队列中。回调在调用时使用 trigger 安排一个 kivy 回调。 .然后kivy的主线程调用的函数调用队列的get函数,并设置相应的属性。

如果您需要设置许多属性,这将很有帮助。如果您只需要设置单个属性,我所做的是从第二个线程安排一个使用 partial 使值成为函数一部分的 callabck。例如:

# this may only be called from the main kivy thread
def set_property(value, *largs):
self.kivy_property = value

# the second thread does this when it wants to set self.kivy_property to 10
Clock.schedule_once(partial(set_property, 10))

关于python - 从另一个线程更改 kivy 属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22031262/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com