我寫了一段處理多個進程的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