Kivy Producer / Consumer Queue更新

时间:2017-10-25 01:47:06

标签: python multiprocessing kivy

希望了解此代码未更新的原因。任何帮助深表感谢。 TJ

这是我的Main.py.在这里,我试图链接一个存储数字生成器进程状态的队列。这是为了模拟一些将随着时间的推移更新用户界面的后台进程。

import Consumer
import Producer
import multiprocessing

if __name__ == '__main__':
   shared_queue = multiprocessing.Queue()

  producer = Producer.NumberGenerator(shared_queue)
   multiprocessing.Process(target=producer.generate_numbers).start()

  app = Consumer.TimerApp()
   app.set_queue(shared_queue)

  app.run()

Producer.py作为单独的进程运行,每秒生成一个新数字。它只是表明后台任务能够不断更新用户界面。

import time


class NumberGenerator(object):

   def __init__(self, q):
        self.q = q
        self.counter = 0

   def generate_numbers(self):
        while True:
            time.sleep(1)
            self.counter += 1
            # print self.counter
            self.q.put(self.counter)

Consumer.py是我们的Kivy应用程序。它意味着通过从中弹出项目来侦听队列。然后,更新UI以演示工作正常。

from kivy.app import App
from kivy.uix.label import Label
from kivy.properties import StringProperty
import multiprocessing


class YourWidget(Label):
   temp = StringProperty()

  def update_text(self, txt):
      self.temp = txt


class TimerApp(App):

  def build(self):
      self.widget = YourWidget()
      self.widget.update_text("Initial Text!")

     # Build registry here
      # Start queue reader here
      # How do I pass in a reference? Setter function??
      return self.widget

  def set_queue(self, q):
      self.q = q

  def consumer_process_queue(self):
      while True:
         value = str(self.q.get())
         print "Consumer: {}".format(value)
         self.widget.update_text(value)

  def on_start(self):
      # self.widget.update_text("Hello World!")
      multiprocessing.Process(target=self.consumer_process_queue).start()

timer.kv:

<YourWidget>:
    text: root.temp

当事情正在处理时,我可以看到数字更新为STDOUT。这表明&#34; self.widget.update_text(value)&#34;没有做我想做的事。 有什么想法吗?

另外,如果我使用评论的&#34; self.widget.update_text(&#34; Hello World!&#34;)&#34;代码并注释掉&#34; multiprocessing.Process(target = self.consumer_process_queue).start()&#34;,小部件更新文本。

1 个答案:

答案 0 :(得分:0)

问题

def consumer_process_queue(self):
    while True:
        value = str(self.q.get())
        print("Consumer: {}".format(value))
        self.widget.update_text(value)

当你运行它时,程序将永远不会退出循环,阻止Kivy完成所有其他需要做的事情。因此,您所看到的只是一个带有“初始文本!”的黑色窗口,您将无法与之交互。

解决方案

相反,您需要“安排”您的consumer_process_queue()函数重复调用。 有关详细信息,请参阅示例。没有对Producer.py和main.py进行任何更改。

实施例

Consumer.py

from kivy.app import App
from kivy.uix.label import Label
from kivy.clock import Clock
import multiprocessing


class YourWidget(Label):

    def update_text(self, txt):
        self.text = txt


class TimerApp(App):

    def build(self):
        self.widget = YourWidget()
        self.widget.update_text("Initial Text!")
        Clock.schedule_interval(self.consumer_process_queue, 1)

        # Build registry here
        # Start queue reader here
        # How do I pass in a reference? Setter function??
        return self.widget

    def set_queue(self, q):
        self.q = q

    def consumer_process_queue(self, dt=0):
        value = str(self.q.get())
        print("Consumer: {}".format(value))
        self.widget.update_text(value)

    def on_start(self):
        # self.update_text("Hello World!")
        multiprocessing.Process(target=self.consumer_process_queue).start()

timer.kv

#:kivy 1.10.0

<YourWidget>:
    text: ""

输出

enter image description here