複数のプロセスを処理する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は、私は、画面の更新を持つように見つけることができる唯一の方法は、self.parent.current = 'program'
を実行した後、残りを実行することでした
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()
ですスレッドとしてコードの。しかし、私は今、スレッドをメイン関数に書き戻して画面を更新するようには思えません。最終的に、テキストが更新されたら、ボックスの色を変更する必要がありますが、それは間に合うでしょう。
問題の最低限の例に役立つだろう。 https://stackoverflow.com/help/mcve – EL3PHANTEN
こんにちは、私は問題の一部ではないと思われる「余分な」コードを削除しました。 – user1086924