Изменение свойства kivy из другого потока

Я экспериментирую с кодом kivy. Я пробовал модифицировать свойство kivy ( text_colour ) из протектора, созданного с помощью threading lib. Программа работает нормально, но нить не изменяет свойство.

Я также попытался создать метод в классе, который получает значение как аргумент, который также потерпел неудачу.

 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/../datahttp://img.rupython.com/pythondefaulttheme.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/../datahttp://img.rupython.com/pythondefaulttheme-0.png> [DEBUG ] [ImagePygame ] Load </usr/lib/python2.7/site-packages/Kivy-1.8.0-py2.7-linux-x86_64.egg/kivy/data/../datahttp://img.rupython.com/pythondefaulttheme-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... 

2 Solutions collect form web for “Изменение свойства kivy из другого потока”

Вы не можете изменять свойство kivy или выполнять любую связанную с OpenGL работу из внешнего потока.

Решение состоит в том, чтобы планировать обратные вызовы с часами 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, чтобы помещать вещи в очередь. И обратный вызов, при вызове, рассылает обратный вызов kivy с помощью триггера . Функция, которая затем вызывает основной поток kivy, вызывает функцию get очереди и устанавливает соответствующее свойство.

Это полезно, если вам нужно задать многие свойства. Если вам просто нужно установить одно свойство, то, что я делаю, из второго потока я планирую 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)) 

Меня устраивает:

 from kivy.app import App from kivy.uix.label import Label import threading import time class ScatterTextWidget(Label): def __init__(self,**kwargs): self.text = 'nima' self.color = [0, 1, 1, 1] super(ScatterTextWidget, self).__init__(**kwargs) a = ScatterTextWidget() def zaaa(): import time time.sleep(3) a.color = [0, 0, 1, 1] print "function ran" t = threading.Thread(target= zaaa) t.start() class TataApp(App): def build(self): return a if __name__ == "__main__": TataApp().run() 
  • Как центрировать текст по горизонтали в текстовом вводе kivy?
  • Time.sleep в Киви
  • Python не может импортировать имя <class>
  • Множественный выбор Kivy с флажками
  • Kivy ObjectProperty для обновления текста ярлыка
  • Изменение текста виджета Kivy
  • Как можно использовать глупый или наглядный вид из киви?
  • Разница между Kivy и Java для приложений для Android
  • Python - лучший язык программирования в мире.