我写了一段处理多个进程的python代码,它工作的很好,但我试图在此代码中添加一个基于Kivy的显示。我已经更新了代码,以便能够使用线程而不是进程。我的问题是,我似乎无法让线程写回屏幕。我正在使用@mainthread
。我找到了一个示例代码here,并且能够获取线程来更新屏幕,但由于某种原因,我的代码似乎无法工作。
- >编辑,我删除了额外的代码,我不相信与我的问题有关。
- >编辑#2:,我仍然简化了代码,我相信是裸露的。仍然显示我有问题。从我读过的,可能是导致我这个问题的x.join
代码,并锁定主循环。我需要运行while循环5次,但一次只能运行2个线程。在继续执行线程之前,需要将while循环保持在非阻塞状态。Kivy多线程和更新屏幕
这里是menu.kv
<ScreenManagement>:
MenuScreen:
ProgramScreen:
<MenuScreen>:
name: 'menu'
AnchorLayout:
GridLayout:
cols: 2
Button
text: "Start Application"
on_release: root.routine()
<ProgramScreen>:
filler1: filler1
filler2: filler2
filler3: filler3
filler4: filler4
name: 'program'
GridLayout:
cols: 4
Button:
id: filler1
text: 'Filler 1'
halign: 'center'
padding_y: '300'
bcolor: 1,0,1,1
Button:
id: filler2
text: 'Filler 2'
halign: 'center'
padding_y: '300'
bcolor: 1,0,0,1
Button:
id: filler3
text: 'Filler 3'
halign: 'center'
padding_y: '300'
bcolor: 1,0,1,0
Button:
id: filler4
text: 'Filler 4'
halign: 'center'
padding_y: '40 '
bcolor: 0,0,1,1
这里是我的main.py
from kivy.app import App
from kivy.uix.togglebutton import ToggleButton
from kivy.uix.widget import Widget
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.gridlayout import GridLayout
from kivy.uix.screenmanager import ScreenManager, Screen, FadeTransition
from kivy.lang import Builder
from kivy.properties import *
from kivy.core.window import Window
from kivy.clock import Clock, mainthread
import threading
import time
########################################################################
class ScreenManagement(ScreenManager):
pass
class MenuScreen(Screen):
def routine(self):
self.parent.current = 'program'
threading.Thread(target=ProgramScreen().build).start()
class ProgramScreen(Screen):
@mainthread
def update_label(self, int_counter, new_text):
if int_counter == 0 :
print "here ", int_counter, new_text
self.filler1.text = new_text
elif int_counter == 1 :
self.filler2.text = new_text
elif int_counter == 2 :
self.filler3.text = new_text
elif int_counter == 3 :
self.filler4.text = new_text
else:
self.filler1.text = "fault"
#dummy function to be replaced with a function that will call GPIO for input and feedback.
def func (self,value):
print 'func', value, 'starting'
for i in xrange(10*(value+1)):
if ((i%3) == 0):
self.update_label(int(value),str(i))
print value, i
time.sleep(1)
print 'func', value, 'finishing'
def build(self):
NumberofFiller = 2
NumberofCells = 5
CellCounter = 0
while CellCounter < NumberofCells:
try:
threads = []
print ('Counter:',CellCounter,'Fillers:',NumberofFiller,'Cells:',NumberofCells)
for i in range (NumberofFiller):
t = threading.Thread(target=self.func, args=((CellCounter%NumberofFiller),))
t.start()
threads.append(t)
CellCounter = CellCounter +1
for x in threads:
#Problem I believe is here.
x.join()
#Need a way to pause the While loop for the first set of threads to finish before starting the next threads.
# print (threads)
except (KeyboardInterrupt, SystemExit):
functions.cleanAndExit()
########################################################################
#Builder.load_file("Menu_red.kv") #Not needed
class Menu_red2App(App):
def build(self):
return ScreenManagement()
#----------------------------------------------------------------------
if __name__ == "__main__":
Menu_red2App().run()
,我能找到有屏幕更新的唯一方法,执行self.parent.current = 'program'
后,运行该休息的代码作为一个线程。但我现在似乎无法让线程回写主功能来更新屏幕。最后,一旦文字被更新,我将需要改变这些框的颜色,但那会在适当的时候出现。
您的问题将帮助小例子。 https://stackoverflow.com/help/mcve – EL3PHANTEN
你好,我已经删除了“我不认为是问题的一部分”的“额外”代码。 – user1086924